Promise 笔记
介绍
Promise是一个对象,它代表了一个异步操作的最终完成或者失败。
本质上Promise是一个函数返回的对象,我们可以在它上面绑定回调函数,这样我们就不需要在一开始把回调函数作为参数传入这个函数了。
约定
在使用Promise时,会有以下约定:
- 在本轮事件循环运行完成之前,回调函数是不会被调用的。
- 即使异步操作已经完成(成功或者失败),在这之后通过then()添加的回调函数也会被调用。
- 通过多次调用then()可以添加多个回调函数,它们会按照插入顺序进行执行。
状态
一个 Promise 必然处于以下几种状态之一:
- 待定(pending):初始状态,既没有被兑现,也没有被拒绝。
- 已兑现(fulfilled):意味着操作成功完成。
- 已拒绝(rejected):意味着操作失败。
链式调用
/** 连续执行两个或者多个异步操作是一个常见的需求,在上一个操作执行成功之后,开始下一个操作,并带着上一步操作所返回的结果。我们可以通过创造一个Promise链来实现这种需求。*/
new Promise((resolve, reject) => {
resolve('略');
})
.then(res => {
res += '略';
return res;
})
.then(res => {
res += '略';
return res;
})
.then(res => {
console.log(res); // 略略略
})
// 注意:一定要有返回值,否则,callback 将无法获取上一个 Promise 的结果。
// 如果使用箭头函数,() => x 比 () => { return x; } 更简洁一些,但后一种保留 return 的写法才支持使用多个语句。
// Promise.prototype.then 和 Promise.prototype.catch 方法返回的是 promise,所以它们可以被链式调用。
Catch的后续链式操作
/** 有可能会在一个回调失败后继续使用链式操作,那么就可以是用catch,这对于在链式操作中抛出一个失败之后,再次进行新的操作会很有用。 */
// 比如说:
new Promise((resolve, reject) => {
console.log('睁开眼睛!');
resolve();
})
.then(() => {
console.log('清晨迈出第一步!');
})
.then(() => {
throw new Error('然后腿断了!');
})
.catch(err => {
console.error(err.message);
console.log('进行治疗!');
})
.then(() => {
console.log('继续迈出第二步!');
})
组合
Promise.resolve() 和 Promise.reject() 是手动创建一个已经 resolve 或者 reject 的Promise快捷方法。
Promise.all() 和 Promise.rece() 是并行运行异步操作的两个组合式工具。
时序
/** 为了避免意外,即使是一个已经变成resolve状态的Promise,传递给then()的函数也总是会被异步调用 */
Promise.resolve().then(() => console.log('黄昏!'))
console.log('清晨!');
// 打印结果
// 清晨!
// 黄昏!
/** 传递到then()中的函数被置入到一个微任务队列中,而不是立即执行,这意味着它是在JavaScript事件队列的所有运行时结束了,且事件队列被清空之后,才开始执行 */
构造函数
Promise()
创建一个新的Promise对象。
该构造函数主要用于包装还没有添加promise支持的函数。
静态方法
Promise.all(iterable)
这个方法返回一个新的promise对象,该promise对象在iterable参数对象里所有的promise对象都成功的时候才会触发成功,一旦有任何一个iterable里面的promise对象失败则立即触发该promise对象的失败。
这个新的promise对象在触发成功状态以后,会把一个包含iterable里所有promise返回值的数组作为成功回调的返回值,顺序跟iterable的顺序保持一致;
如果这个新的promise对象触发了失败状态,它会把iterable里第一个触发失败的promise对象的错误信息作为它的失败错误信息。
Promise.all方法常被用于处理多个promise对象的状态集合。
Promise.allSettled(iterable)
等到所有promises都已敲定,每个promise都已兑现(fulfilled)或已拒绝(rejected)。
返回一个promise,该promise在所有promise完成后完成。并带有一个对象数组,每个对象对应每个promise的结果。
Promise.any(iterable)
接收一个Promise对象的集合,党旗红一个promise成功,就返回那个成功的promise的值
Promise.race(iterable)
当iterable参数里的任意一个子promise被成功或失败后,父promise马上也会用子promise的成功返回值或失败详情作为参数调用父promise绑定的相应句柄,并返回该promise对象。
Promise.reject(reason)
返回一个状态为失败的Promise对象,并将给定的失败信息传递给对应的处理方法。
Promise.resolve(value)
返回一个状态由给定value决定的Promise对象。
如果该值是thenable(即,带有then方法的对象),返回Promise对象的最终状态由then方法执行决定。
否则的话(比如该value为空,基本类型、不带then方法的对象)返回的Promise对象状态为fulfilled,并且将该value传递给对应的then方法。
如果不知道一个值是否是Promise对象,那么可以使用Promise.resolve(value)来返回一个Promise对象,这样就能将该value以Promise对象形式使用。
Promise 原型
属性
Promise.prototype.constructor
返回被创建的实例函数,默认为Promise函数
函数
Promise.prototype.catch(onRejected)
添加一个拒绝(rejected)回调到当前promise,返回一个新的promise。
当这个回调函数被调用,新 promise 将以它的返回值来resolve,否则如果当前promise 进入fulfilled状态,则以当前promise的完成结果作为新promise的完成结果.
Promise.prototype.then(onFulfilled, onRejected)
添加解决(fulfillment)和拒绝(rejection)回调到当前 promise, 返回一个新的 promise, 将以回调的返回值来resolve
Promise.prototype.finally(onFinally)
添加一个事件处理回调于当前promise对象,并且在原promise对象解析完毕后,返回一个新的promise对象。
回调会在当前promise运行完毕后被调用,无论当前promise的状态是完成(fulfilled)还是失败(rejected)
Promise 的基本使用
// Promise 对象是由关键字 new 及其构造函数来创建的
// 接受两个函数 resolve 和 reject
// 成功的回调 与 失败的回调
const promise = new Promise((resolve, reject) => {
// 在此进行一些操作判断,最终会调用下面两者之一:
resolve(); // fulfilled
// 或
reject(); // rejected
});