记录一些Promise笔记

488 阅读5分钟

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
});