0%

JavaScript中Promise记录

简介

JavaScript中都是单线程执行,导致所有的网络操作,浏览器操作都必须异步执行。Promise异步执行时回调函数可以链式条用,Promise有各种开源实现,ES6中被统一规范,由浏览器直接支持。

用法

简单示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function test(resolve, reject) {
var timeOut = Math.random() * 2;
log('set timeout to: ' + timeOut + ' seconds.');
setTimeout(function () {
if (timeOut < 1) {
log('call resolve()...');
resolve('200 OK');
}
else {
log('call reject()...');
reject('timeout in ' + timeOut + ' seconds.');
}
}, timeOut * 1000);
}

在方法中有resolve和reject两个方法,如果执行成功,则调用resolve(),执行失败调用reject(),函数只关心自身逻辑,不关心具体的resolve和reject方法。

生成Promise对象:

1
2
3
4
5
new Promise(test).then(function (result) {
console.log('成功:' + result);
}).catch(function (reason) {
console.log('失败:' + reason);
});

Promise处理流程

Promise处理流程

串行执行

1
job1.then(job2).then(job3).catch(handleError);

异步执行多个任务

1
2
3
4
5
6
7
8
9
10
var p1 = new Promise(function (resolve, reject) {
setTimeout(resolve, 500, 'P1');
});
var p2 = new Promise(function (resolve, reject) {
setTimeout(resolve, 600, 'P2');
});
// 同时执行p1和p2,并在它们都完成后执行then:
Promise.all([p1, p2]).then(function (results) {
console.log(results); // 获得一个Array: ['P1', 'P2']
});

多个任务获取先返回的结果

1
2
3
4
5
6
7
8
9
var p1 = new Promise(function (resolve, reject) {
setTimeout(resolve, 500, 'P1');
});
var p2 = new Promise(function (resolve, reject) {
setTimeout(resolve, 600, 'P2');
});
Promise.race([p1, p2]).then(function (result) {
console.log(result); // 'P1'
});

由于p1执行较快,Promise的then()将获得结果'P1'p2仍在继续执行,但执行结果将被丢弃。