概念
Promise是一个对象,它代表了一个异步操作的最终完成或者失败。
Promise 对象有三种状态:Pending(初始状态,既不是成功,也不是失败状态)、Resolved(已完成,又称 Fulfilled)和 Rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态,并且一旦状态改变,就不会再变,会一直保持这个结果。即使对已经发生变化的 Promise 对象添加回调函数,也会立即得到这个结果。
创建Promise
创建Promise实例时会传入两个方法:resolve和reject,调用resolve会把promise的状态置为 fullfiled,反之reject会把promise的状态置为rejected,这样在then中我们就能捕获到并执行对应的回调。
new Promise((resolve, reject) => {
setTimeout(function () {
resolve("200 OK");
}, 1000);
}).then((result) => {
console.log("成功:" + result);
}, (reason) => {
console.log("失败:" + reason);
});
除了手动调用reject方法之外,Promise也会自动捕获内部异常,并交给rejected响应函数处理。
new Promise((resolve, reject) => {
throw new Error("错误信息");
}).then((result) => {
console.log("成功:" + result);
}, (reason) => {
console.log("失败:" + reason);
});
一旦遇到异常抛出,浏览器就会顺着promise链寻找下一个失败回调函数,因此使用throw new Error方式处理错误可以捕获前面所有的错误。
new Promise(() => {
console.log('start...');
throw new Error('this is a error');
}).catch(err => {
console.error('i catch:', err);
throw new Error('this is another error');
}).then(() => {
console.log('test');
}).then(() => {
console.log('test2');
}).catch(err => {
console.error('I also catch',err);
});
表面看来Promise的作用是简化层层回调的写法,然而Promise的真正的精髓是“状态”,用维护状态、传递状态的方式来使得回调函数能够及时调用,相对于传递callback函数来说要更简单、灵活。
new Promise((resolve, reject) => {
setTimeout(resolve, 300, 'promise1');
}).then((result) => {
return new Promise((resolve, reject) => {
setTimeout(resolve, 400, 'promise2');
});
}).then((newResult) => {
return new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'promise3');
});
}).then((finalResult) => {
console.log('Got the final result: ' + finalResult);
}).catch((reason) => {
console.log("失败:" + reason);
});
catch
then里的参数是可选的,catch(failureCallback) 是 then(null, failureCallback) 的缩略形式。
new Promise((resolve, reject) => {
setTimeout(function () {
reject("400");
}, 1000);
}).then((result) => {
console.log("成功:" + result);
}).catch((reason) => {
console.log("失败:" + reason);
});
finally
finally() 方法返回一个Promise。在promise结束时,无论结果是fulfilled或者是rejected,都会执行指定的回调函数。这为在Promise是否成功完成后都需要执行的代码提供了一种方式。
这避免了同样的语句需要在then()和catch()中各写一次的情况。
Promise.all()
Promise.all()接收一个数组参数,里面的值最终都会返回Promise对象。这样,三个异步操作的并行执行的,等到它们都执行完后,并且都是resolve才会进到then里面。只要任何一个输入的promise的reject回调执行或者输入不合法的promise就会立即抛出错误,并且reject的是第一个抛出的错误信息。
const promise1 = new Promise((resolve, reject) => {
setTimeout(resolve, 300, 'promise1');
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(resolve, 400, 'promise2');
});
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'promise3');
});
Promise.all([promise1, promise2, promise3]).then((values) => {
console.log(values);
});
Promise.race()
不同于Promise.all()需要所有异步操作都执行完后才会进到then里面,Promise.race()只需要任意一个promise状态变更为成功或者失败就会进到then或catch里面。
const promise1 = new Promise((resolve, reject) => {
setTimeout(resolve, 300, 'promise1');
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(resolve, 400, 'promise2');
});
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'promise3');
});
Promise.race([promise1, promise2, promise3]).then((values) => {
console.log(values);
});
Promise.any()
区别于Promise.all()的必须全部成功以及Promise.race的以第一个有返回的promise结果状态为准,Promise.any()只需要任意一个promise成功resolve则进入then,如果所有的promise都reject,则抛出异常表示所有请求失败。
const promise1 = new Promise((resolve, reject) => {
setTimeout(reject, 300, 'promise1');
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(resolve, 400, 'promise2');
});
const promise3 = new Promise((resolve, reject) => {
setTimeout(reject, 100, 'promise3');
});
Promise.any([promise1, promise2, promise3]).then((values) => {
console.log(values);
});
Promise.allSettled()
Promise.all()必须全部成功,Promise.any()需要至少一个成功,而Promise.allSettled()方法会在所有给定的promise都已经fulfilled或rejected后返回一个对象数组,每个对象表示对应的promise结果。
const promise1 = new Promise((resolve, reject) => {
setTimeout(reject, 300, 'promise1');
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(resolve, 400, 'promise2');
});
const promise3 = new Promise((resolve, reject) => {
setTimeout(reject, 100, 'promise3');
});
Promise.allSettled([promise1, promise2, promise3]).then((values) => {
console.log(values);
});
Promise.reject()
Promise.reject()方法返回一个带有拒绝原因的Promise对象。
Promise.resolve()
Promise.resolve(value)方法返回一个以给定值解析后的Promise 对象。如果这个值是一个 promise ,那么将返回这个 promise;如果这个值是thenable(即带有"then" 方法),返回的promise会“跟随”这个thenable的对象,采用它的最终状态;否则返回的promise将以此值完成。此函数将类promise对象的多层嵌套展平。