手写简单版promise (二)

·  阅读 69

这是我参与8月更文挑战的第4天,活动详情查看:8月更文挑战

前言

本文为手写一个基础版 promise ,用于理解其常用方法。涉及的方法有 then、all、race、resolve、reject、finally、catch,其中 all、race、resolve、reject为静态方法即在方法名前面添加 static 关键字(在本文中先实现race、resolve、reject、finally、catch)

race 方法

是一个静态方法,需要一个数组作为参数,返回一个 Promise
返回 promise 的状态与值取决于数组参数中第一个完成状态变更的数组项

定义要返回的新 promise 对象。对参数数组中的每一项来进行执行操作,若该项是一个 promise 对象,则通过其 then 方法来间接触发新 promise 的状态变更方法;若该项是一个非 promise 对象,则认定新 promise 的状态为成功,值为该项。此处注意将非 promise 对象包一层异步操作。

static race (arr) {
    const racePromise = new MyPromise((resolve, reject) => {
        arr.forEach(item => {
            if (item instanceof MyPromise) {
                item.then(resolve, reject);
            } else {
                queueMicrotask(() => { // 对于非 promise 对象,直接判定其执行成功的回调,但需加一层异步处理,因为 promise 的状态变更是异步的,为保证数组内各项参数触发顺序的一致
                    resolve(item);
                });
            }
        })
    });
    return racePromise;
}
复制代码

resolve 方法

是一个静态方法,接收一个参数,返回一个promise
返回的 promise 的状态与参数有关,若参数是一个 promise,则直接返回这个 promise;否则新 promise 的状态为成功,值为参数值

static resolve (val) {
    if (val instanceof MyPromise) return val;
    return new MyPromise(resolve => {
        resolve(val);
    });
}
复制代码

reject 方法

是一个静态方法,接受一个参数,返回一个 promise
返回的 promise 状态为失败,值为传入的参数

static reject (reason) {
    return new MyPromise((resolve, reject) => {
        reject(reason);
    });
}
复制代码

finally 方法

接收一个参数,如果是函数的话就执行并获取返回值;返回一个 promise,状态和值与调用该方法的 promise 状态和值相同 直接使用 peomise 静态的resolve方法来构建返回的 promise 即可。

finally (callback) {
    let x = typeof callback === 'function' ? callback() : callback; // 做代码容错,提高健壮性
    return MyPromise.resolve(x).then(() => this);
    // 为什么不写成下面这种形式
    // 1, 错误的回调中为什么要用 throw, 因为 throw 可以保存当前的错误状态
    // 2, 为什么错误的回调要删除不写,因为在 MyPromise 的 then 方法中,对传入的成功回调和错误回调做了容错处理,当前的错误回调形式与 then 中默认的错误回调相同,故在此处省略不写
    // return MyPromise.resolve(x).then(() => this, reason => { throw reason });
}
复制代码

catch 方法

接收一个错误回调函数,该方法只会在 promise 错误时触发
故直接通过自身 then 方法接收错误的回调即可。

catch (onRejected) {
    return this.then(null, onRejected);
}
复制代码

参考

# 「景水」- 手写 Promise 心得分享
简易版 promise 手写就到此为止,欢迎提出建议。源码在这里

分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改