抽象异步处理对象以及对其进行各种操作的组件
Constructor
构造函数Instance Method
实例方法Static Method
静态方法**promise.then(onFulfilled, onRejected)
操作之后执行回调函数。**Fulfilled为执行成功调用的函数,onRejected为执行失败调用的函数。
promise.catch(onRejected)
捕获到错误执行onRejected函数
graph LR
Pending-->Fulfilled
Pending-->Rejected
new Promise
方法创建promise对象。.then
或.then
添加promise对象的处理函数。静态方法Promise.resolve(value) 可以认为是 new Promise() 方法的快捷方式。
new Promise(function(resolve){
resolve(42);
});
function taskA() {
console.log("Task A");
}
function taskB() {
console.log("Task B");
}
function onRejected(error) {
console.log("Catch Error: A or B", error);
}
function finalTask() {
console.log("Final Task");
}
var promise = Promise.resolve();
promise
.then(taskA)
.then(taskB)
.catch(onRejected)
.then(finalTask);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8gGAh3eC-1585579112930)(http://liubin.org/promises-book/Ch2_HowToWrite/img/promise-then-catch-flow.png)]
function doubleUp(value) {
return value * 2;
}
function increment(value) {
return value + 1;
}
function output(value) {
console.log(value);// => (1 + 1) * 2
}
var promise = Promise.resolve(1);
promise
.then(increment)
.then(doubleUp)
.then(output)
.catch(function(error){
// promise chain中出现异常的时候会被调用
console.error(error);
});
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t66Chbo0-1585579112952)(http://liubin.org/promises-book/Ch2_HowToWrite/img/promise-then-passing-value.png)]
Promise.all
接收一个 promise对象的数组作为参数,当这个数组里的所有promise对象全部变为resolve或reject状态的时候,它才会去调用 .then
方法。
Promise.all([request.comment(), request.people()]);
request.comment()
与request.people()
会同时执行(并行执行)。Promise.race
只要有一个promise对象进入 FulFilled 或者 Rejected 状态的话,就会继续进行后面的处理。
注:promise.race在第一个函数执行完毕后,并不会取消其他函数的执行状态,但是其余函数执行完毕之后不会再调用.then
。
.catch
也可以理解为 promise.then(undefined, onRejected),但实际使用中我们还是会将then与catch分开使用。
建议多用catch方法,少用then方法的第二个参数
function throwError(value) {
// 抛出异常
throw new Error(value);
}
// <1> onRejected不会被调用
function badMain(onRejected) {
return Promise.resolve(42).then(throwError, onRejected);
}
// <2> 有异常发生时onRejected会被调用
function goodMain(onRejected) {
return Promise.resolve(42).then(throwError).catch(onRejected);
}
// 运行示例
badMain(function(){
console.log("BAD");
});
goodMain(function(){
console.log("GOOD");
});
//输出结果
`GOOD`
.then
即使 throwError 抛出了异常,onRejected 指定的函数也不会被调用。.catch
因为是链式操作,会捕获到上一步.then
中抛出的操作。const someAsyncThing = function() {
return new Promise(function(resolve, reject) {
// 下面一行会报错,因为x没有声明
resolve(x + 2);
});
};
someAsyncThing().then(function() {
console.log('everything is great');
});
setTimeout(() => { console.log(123) }, 2000);
// Uncaught (in promise) ReferenceError: x is not defined
// 123
process.on('unhandledRejection',function (err, p) {
throw err;
});
有时需要将现有对象转为 Promise 对象,Promise.resolve方法就起到这个作用。
thenable
对象,(thenable对象指的是具有then方法的对象,代码如下),会将这个对象转为 Promise 对象然后立即执行它的then方法let thenable = {
then: function(resolve, reject) {
resolve(42);
}
};
const jsPromise = Promise.resolve($.ajax('/whatever.json'));
Promise 对象的回调链,不管以then方法或catch方法结尾,要是最后一个方法抛出错误,都有可能无法捕捉到(因为 Promise 内部的错误不会冒泡到全局)。因此,我们可以提供一个done方法,总是处于回调链的尾端,保证抛出任何可能出现的错误。
asyncFunc()
.then(f1)
.catch(r1)
.then(f2)
.done();
Promise.prototype.done = function (onFulfilled, onRejected) {
this.then(onFulfilled, onRejected)
.catch(function (reason) {
// 抛出一个全局错误
setTimeout(() => { throw reason }, 0);
});
};
done都会捕捉到任何可能出现的错误,并向全局抛出。
finally方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。只要proise对象出现最后状态,finally方法就一定会执行。
类似于一个函数的回调。
server.listen(0)
.then(function () {
// run test
})
.finally(server.stop);
Promise.prototype.finally = function (callback) {
let P = this.constructor;
return this.then(
value => P.resolve(callback()).then(() => value),
reason => P.resolve(callback()).then(() => { throw reason })
);
};