JS-Promise

106 阅读5分钟

异步任务处理

  • 通过回调函数,成功返回一个成功函数,失败返回一个失败函数
  • 弊端:
    • 自己封装的请求函数,需要设计好callback名称,使用很麻烦
    • 使用别人封装的请求函数,需要阅读源码或文档,沟通成本较大

Promise

  • Promiese是一个
  • 在通过new创建Promise时,需要入一个回调函数(executor)
    • 回调函数立即执行,并且给传入另外两个回调函数resolve,reject
    • 调用resolve时,会执行Promise对象的then方法传入的回调函数
    • 调用reject时,会执行Promise对象的catch方法传入的回调函数

Promise对象方法

Promise.prototype

  • image.png

Executor

  • 创建Promise时需要传入的一个回调函数,这个回调函数会立即执行,并且传入两个参数resolvereject
  • 通常在Executor中确Promise状态
    • resolve()可以将pending => fulfilled
    • reject()可以将pending => rejected
    • 一但状态被确定下来,之后就可以更改

resolve参数

  • 传入普通值或者对象,这个会作为then回调的参数
  • 传入的是新的Promise,Promise的状态新的Promise决定
  • 传入的对象中含有then函数(实现了thenable接口),就会执行该then方法,Promise的状态由该then方法的结果来决定

then方法

  • 是放在Promise原型上的Promise.prototype.then
  • 接收两个参数
    • fulfilled的回调函数:状态变为fulfilled时回调
    • rejected的回调函数:状态变为rejected时回调
  • 一个Promisethen方法可以多次调用
    • 每次调用都可以传入对应的fulfilled回调
    • Promise的状态变成fulfilled时,这些回调函数都会被执行
  • then方法返回值
    • then方法本身返回值,它的返回值是一个Promise,可以进行链式调用
  • Promise有三种状态,then方法返回的Promise状态
    • then方法中的回调函数本身在执行的时候,那么它处于pending状态
    • 当then方法中的回调函数返回一个结果时,那么它处于fulfilled状态,并且会将结果作为resolve参数
      • 返回一个普通的值
      • 返回一个Promise
      • 返回一个thenable
    • then方法发抛出一个异常时,那么它处于rejected状态

catch方法(ES6)

  • 是放在Promise原型上的Promise.prototype.catch

  • fulfilledrejected都写在then方法中,阅读性太差。

  • ES6新增catch方法来传入reject回调函数,但这种写法符合 Promise/A+ 规范

  • 一个Promisecatch方法可以多次调用

    • 每次调用都可以传入对应的rejected回调
    • Promise的状态变成rejected时,这些回调函数都会被执行
  • catch方法返回值

    • catch方法本身返回值,它的返回值是一个Promise,可以进行链式调用,后面继续thencatch调用
    • catch传入的回调函数执行完之后,默认状态依然是fulfilled,会回调下一个then
    • 如果希望执行后继续执行catch,需要抛出异常,就会回下一个catch

finally方法(ES9)

  • ES9新增,表示无论Promise对象变成fulfilled还是rejected状态,最终都会被执行代码
  • 不接收参数不论什么状态都会执行

Promise类方法

Promise.prototype.constructor

  • image.png

resolve方法

  • Promise.resolve的用法相当于new Promise,并且执行resolve操作

  • 现有内容转成Promise对象

    // 转成Promise对象
    function toPromise() {
        const obj = {
            name: "zzy",
        };
        return new Promise((resolve) => {
            resolve(obj);
        });
    }
    toPromise().then((res) => {
        console.log(res); // { name: 'zzy' }
    });
    
    // 类方法Promise.resolve
    // 1.传入普通的值
    Promise.resolve({ name: "lll" }).then((res) => console.log(res)); // { name: 'lll' }
    
    // 相当于new Promise
    new Promise((resolve, reject) => {
        resolve({ name: "aaa" });
    }).then((res) => console.log(res)); // { name: 'aaa' }
    
    // 2.传入Promise
    Promise.resolve(
        new Promise((resolve, reject) => {
            resolve("promise");
        })
    ).then((res) => console.log(res)); // 111
    
    // 3.传入thenable
    Promise.resolve({
        then(resolve, reject) {
            resolve("thenable");
        },
    }).then((res) => console.log(res)); // thenable
    

reject方法

  • reject方法类似resolve方法,只是会将Promise对象的状态设置为rejected状态

  • Promise.reject的用法相当于new Promise,并且执行reject操作

  • Promise.reject传入的参数无论是什么形态不做处理,直接作为rejected参数传递到catah

  • // 类方法Promise.reject
    // 无论传入什么值都一样
    // 1.传普通值
    Promise.reject("reject err").catch((err) => console.log(err)); // reject err
    
    // 相当于
    new Promise((resolve, reject) => {
        reject("promise err");
    }).catch((err) => console.log(err)); // promise err
    
    // 2.传入Promise
    Promise.reject(new Promise(() => {})).then(
        (res) => console.log(res, "res"), // 不会去回调resolve
        (err) => console.log(err, "err")
    ); // Promise { <pending> } err
    
    // 3.传thenable
    Promise.reject({
        then(resolve, reject) {
            reject("thenable");
        },
    }).then(
        (res) => console.log(res, "res"), // 不会去回调resolve
        (err) => console.log(err, "err")
    ); // { then: [Function: then] } err
    

all方法

  • 所有Promise都变成fulfilled时,拿到结果

  • 一个Promise为rejected时,那么整个Promise为rejected

  • 缺陷

    • 一个Promise为rejected时,那么整个Promise为rejected,对于resolved的和pending状态的Promise获取不到对应结果
  • // 创建多个Promise
    const p1 = new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve("resolve1");
        }, 1000);
    });
    const p2 = new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve("resolve2");
        }, 2000);
    });
    const p3 = new Promise((resolve, reject) => {
        setTimeout(() => {
            reject("reject1");
        }, 3000);
    });
    
    // 所有Promise都变成fulfilled时,再拿到结果
    Promise.all([p1, p2]).then((res) => console.log(res));
    // 有1个Promise为rejected时,那么整个Promise为rejected
    Promise.all([p1, p3]).then(
        (res) => console.log(res),
        (err) => console.log(err)
    );
    
    

allSettled方法(ES11)

  • ES11新增,Promise.allSettled会在所有Promise不论什么状态)都有结果settled)时才会有最终状态
  • 并且这个Promise结果一定是fulfilled

race方法

  • 一个Promise最先改变状态为fulfilled,直接返回结果,跳出执行
  • 如果最先改变为rejected,则直接catchreject的结果

any方法(ES12)

  • race方法类似
  • 至少有一个变为fulfilled,才会决定新Promise状态
  • 如果所有Promise都是reject,也会等到所有Promise变为rejected状态,会报错AggregateError
  • err.errors
  • 所有错误放到一个数组中返回
  • new ArrayregateError(ES12)