关于javascript:promise实现原理一

38次阅读

共计 3128 个字符,预计需要花费 8 分钟才能阅读完成。

        // 三种状态
        const PENDING = "pending";
        const RESOLVED = "resolved";
        const REJECTED = "rejected";
        // promise 接管一个函数参数,该函数会立刻执行
        function MyPromise(fn) {
            let _this = this;
            _this.currentState = PENDING;
            _this.value = undefined;
            // 用于保留 then 中的回调,只有当 promise
            // 状态为 pending 时才会缓存,并且每个实例至少缓存一个
            _this.resolvedCallbacks = [];
            _this.rejectedCallbacks = [];
            _this.resolve = function (value) {if (value instanceof MyPromise) {
                    // 如果 value 是个 Promise,递归执行
                    return value.then(_this.resolve, _this.reject);
                }
                setTimeout(() => {
                    // 异步执行,必须保障执行程序
                    if (_this.currentState === PENDING) {
                        _this.currentState = RESOLVED;
                        _this.value = value;
                        _this.resolvedCallbacks.forEach((cb) => cb());
                    }
                });
            };
            _this.reject = function (reason) {setTimeout(() => {
                    // 异步执行,保障执行程序
                    if (_this.currentState === PENDING) {
                        _this.currentState = REJECTED;
                        _this.value = reason;
                        _this.rejectedCallbacks.forEach((cb) => cb());
                    }
                });
            };
            // 用于解决以下问题
            // new Promise(() => throw Error('error))
            try {fn(_this.resolve, _this.reject);
            } catch (e) {_this.reject(e);
            }
        }
        MyPromise.prototype.then = function (onResolved, onRejected) {
            var self = this;
            // 标准 2.2.7,then 必须返回一个新的 promise
            var promise2;
            // 标准 2.2.onResolved 和 onRejected 都为可选参数
            // 如果类型不是函数须要疏忽,同时也实现了透传
            // Promise.resolve(v).then().then((value) => console.log(value))
            onResolved =
                typeof onResolved === "function" ? onResolved : (v) => v;
            onRejected = typeof onRejected === "function" ? onRejected : (r) => {throw r};
            if (self.currentState === RESOLVED) {return (promise2 = new MyPromise(function (resolve, reject) {
                    // 标准 2.2.4,保障 onFulfilled,onRjected 异步执行
                    // 所以用了 setTimeout 包裹下
                    setTimeout(function () {
                        try {var x = onResolved(self.value);
                            resolutionProcedure(promise2, x, resolve, reject);
                        } catch (reason) {reject(reason);
                        }
                    });
                }));
            }
            if (self.currentState === REJECTED) {return (promise2 = new MyPromise(function (resolve, reject) {setTimeout(function () {
                        // 异步执行 onRejected
                        try {var x = onRejected(self.value);
                            resolutionProcedure(promise2, x, resolve, reject);
                        } catch (reason) {reject(reason);
                        }
                    });
                }));
            }
            if (self.currentState === PENDING) {return (promise2 = new MyPromise(function (resolve, reject) {self.resolvedCallbacks.push(function () {
                        // 思考到可能会有报错,所以应用 try/catch 包裹
                        try {var x = onResolved(self.value);
                            resolutionProcedure(promise2, x, resolve, reject);
                        } catch (r) {reject(r);
                        }
                    });
                    self.rejectedCallbacks.push(function () {
                        try {var x = onRejected(self.value);
                            resolutionProcedure(promise2, x, resolve, reject);
                        } catch (r) {reject(r);
                        }
                    });
                }));
            }
        };
        // 标准 2.3
        function resolutionProcedure(promise2, x, resolve, reject) {
            // 标准 2.3.1,x 不能和 promise2 雷同,防止循环援用
            if (promise2 === x) {return reject(new TypeError("Error"));
            }
            // 标准 2.3.2
            // 如果 x 为 Promise,状态为 pending 须要持续期待否则执行
            if (x instanceof MyPromise) {if (x.currentState === PENDING) {x.then(function (value) {
                        // 再次调用该函数是为了确认 x resolve 的
                        // 参数是什么类型,如果是根本类型就再次 resolve
                        // 把值传给下个 then
                        resolutionProcedure(promise2, value, resolve, reject);
                    }, reject);
                } else {x.then(resolve, reject);
                }
                return;
            }
            // 标准 2.3.3.3.3
            // reject 或者 resolve 其中一个执行过得话,疏忽其余的
            let called = false;
            // 标准 2.3.3,判断 x 是否为对象或者函数
            if (x !== null && (typeof x === "object" || typeof x === "function")) {
                // 标准 2.3.3.2,如果不能取出 then,就 reject
                try {
                    // 标准 2.3.3.1
                    let then = x.then;
                    // 如果 then 是函数,调用 x.then
                    if (typeof then === "function") {
                        // 标准 2.3.3.3
                        then.call(
                            x,
                            (y) => {if (called) return;
                                called = true;
                                // 标准 2.3.3.3.1
                                resolutionProcedure(promise2, y, resolve, reject);
                            },
                            (e) => {if (called) return;
                                called = true;
                                reject(e);
                            }
                        );
                    } else {
                        // 标准 2.3.3.4
                        resolve(x);
                    }
                } catch (e) {if (called) return;
                    called = true;
                    reject(e);
                }
            } else {
                // 标准 2.3.4,x 为根本类型
                resolve(x);
            }
        }

正文完
 0