乐趣区

关于前端:手写Promise-常用静态方法allresolverejectrace

手写 Promise – 实现一个根底的 Promise
手写 Promise – 实例办法 catch、finally
手写 Promise – 罕用静态方法 all、any、resolve、reject、race

先来回顾一下,上一章节之后的代码。

class WPromise {
    static pending = 'pending';
    static fulfilled = 'fulfilled';
    static rejected = 'rejected';

    constructor(executor) {
        this.status = WPromise.pending; // 初始化状态为 pending
        this.value = undefined; // 存储 this._resolve 即操作胜利 返回的值
        this.reason = undefined; // 存储 this._reject 即操作失败 返回的值
        // 存储 then 中传入的参数
        // 至于为什么是数组呢?因为同一个 Promise 的 then 办法能够调用屡次
        this.callbacks = [];
        executor(this._resolve.bind(this), this._reject.bind(this));
    }

    // onFulfilled 是胜利时执行的函数
    // onRejected 是失败时执行的函数
    then(onFulfilled, onRejected) {
        // 返回一个新的 Promise
        return new WPromise((nextResolve, nextReject) => {
            // 这里之所以把下一个 Promsie 的 resolve 函数和 reject 函数也存在 callback 中
            // 是为了将 onFulfilled 的执行后果通过 nextResolve 传入到下一个 Promise 作为它的 value 值
            this._handler({
                nextResolve,
                nextReject,
                onFulfilled,
                onRejected
            });
        });
    }

    // catch 办法只有一个参数用于处理错误的状况
    catch(onRejected) {return this.then(null, onRejected);
    }

    finally(onFinally) {return this.then(onFinally, onFinally);
    }

    _resolve(value) {
        // 解决 onFulfilled 执行后果是一个 Promise 时的状况
        // 这里可能了解起来有点艰难
        // 当 value instanof WPromise 时,阐明以后 Promise 必定不会是第一个 Promise
        // 而是后续 then 办法返回的 Promise(第二个 Promise)// 咱们要获取的是 value 中的 value 值(有点绕,value 是个 promise 时,那么外部存有个 value 的变量)// 怎么将 value 的 value 值获取到呢,能够将传递一个函数作为 value.then 的 onFulfilled 参数
        // 那么在 value 的外部则会执行这个函数,咱们只须要将以后 Promise 的 value 值赋值为 value 的 value 即可
        if (value instanceof WPromise) {
            value.then(this._resolve.bind(this),
                this._reject.bind(this)
            );
            return;
        }

        this.value = value;
        this.status = WPromise.fulfilled; // 将状态设置为胜利

        // 告诉事件执行
        this.callbacks.forEach(cb => this._handler(cb));
    }

    _reject(reason) {if (reason instanceof WPromise) {
            reason.then(this._resolve.bind(this),
                this._reject.bind(this)
            );
            return;
        }

        this.reason = reason;
        this.status = WPromise.rejected; // 将状态设置为失败

        this.callbacks.forEach(cb => this._handler(cb));
    }

    _handler(callback) {
        const {
            onFulfilled,
            onRejected,
            nextResolve,
            nextReject
        } = callback;

        if (this.status === WPromise.pending) {this.callbacks.push(callback);
            return;
        }

        if (this.status === WPromise.fulfilled) {
            // 传入存储的值
            // 未传入 onFulfilled 时,将 undefined 传入
            const nextValue = onFulfilled
                ? onFulfilled(this.value)
                : this.value;
            nextResolve(nextValue);
            return;
        }

        if (this.status === WPromise.rejected) {
            // 传入存储的错误信息
            // 同样的解决
            const nextReason = onRejected
                ? onRejected(this.reason)
                : this.reason;
            nextReject(nextReason);
        }
    }
}

本章节持续欠缺它,向 Promise 类中增加静态方法 resolve、reject、all、race

Resolve、Reject

Promise.resolve(1).then(data => console.log(data)); // 1
Promise.resolve(new Promise((resolve) => resolve(2))).then(data => console.log(data)); // 2

不言而喻,Promise.resolve(value) 只是一个 resolve 的语法糖,返回一个 Promise 对象。须要留神的一点是如果 value 自身就是一个 promise 或者含有 then 办法的对象,那么就间接返回 value。

代码如下:

class WPromise {
    ...
    // reject 的实现是一样的,只是最初调用的是 reject 而不是 resolve 办法
    static resolve(value) {
        // 判断是否是 thenable 对象
        if (value instanceof WPromise || ((typeof value === 'object') && 'then' in value)) {return value;}
        
        return new WPromise((resolve) => resolve(value));
    }
    ...
}

Promise.all

Promise.all(iterable) 办法返回一个 Promise 实例,此实例在 iterable 参数内所有的 promise 都“实现(resolved)”或参数中不蕴含 promise 时回调实现(resolve);如果参数中 promise 有一个失败(rejected),此实例回调失败(reject),失败的起因是第一个失败 promise 的后果。

下面是 MDN 上对于 Promise.all 的解释。

  1. 承受一个数组,如果数组中有非 promise 对象,则转换成 promise 对象
  2. 返回一个 promise 实例
  3. 数组中所有 promise 执行胜利之后才返回胜利状态,并且返回的 promise 的值就是所有 promise 执行胜利的状态值
  4. 如果有一个 promise 执行失败,则返回失败,并且返回的 promise 的值就是第一个 promise 失败的起因
class WPromise {
    ...
    static all(iterable) {return new WPromise((resolve, reject) => {const ret = [];
            let count = 0;
        
            Array.from(iterable).forEach((item, index) => {WPromise.resolve(item).then(data => {ret[index] = data;
                    count++;
        
                    if (count === iterable.length) {resolve(ret);
                    }
                }, reject);
            });
        });
    }
    ...
}

Promise.race

Promise.race(iterable) 办法返回一个 promise,一旦迭代器中的某个 promise 解决或回绝,返回的 promise 就会解决或回绝。

这个没啥好说的,间接就是返回一个 Promise 就完事。

class WPromise {
    ...
    static race(iterable) {return new WPromise((resolve, reject) => {Array.from(iterable).forEach(item => {WPromise.resolve(item).then(resolve, reject);
            });
        });
    }
    ...
}

以上内容,根本就是所有的 Promise 的内容了。当然还有很多细节的方面没有解决,如果异样解决、边界断定等等。

更多:上述模仿 Promise 的残缺代码

退出移动版