• 手写promise


    // _Promise.js
    // 先定义三个常量表示状态
    const PENDING = 'pending';
    const FULFILLED = 'fulfilled';
    const REJECTED = 'rejected';
    
    function isFunction(fn) {
        return typeof fn === 'function';
    }
    function isObject(ob) {
        return typeof ob === 'object';
    }
    function isNull(value) {
        return value === null;
    }
    function resolvePromise(promise, value, resolve, reject) {
        // 自己调用自己
        if (promise === value) {
            return reject(new TypeError('Chaining cycle detected for promise #<Promise>'));
        }
    
        // if (value instanceof _Promise) {
        //     value.then(resolve, reject);
        // } else {
        //     resolve(value);
        // }
        if (isFunction(value) || isObject(value)) {
            if (isNull(value)) {
                return resolve(value);
            }
            let then;
            try {
                then = value.then;
            } catch (err) {
                return reject(err);
            }
            if (isFunction(then)) {
                // then里面resolve 和 reject 只能有一个执行,因此加一个锁。
                let called = false;
                try {
                    then.call(
                        // this 指向value
                        value,
                        // resolve
                        val => {
                            if (called) return;
                            called = true;
                            resolvePromise(promise, val, resolve, reject);
                        },
                        // reject
                        val => {
                            if (called) return;
                            called = true;
                            reject(val);
                        }
                    );
                } catch (err) {
                    if (called) return;
                    return reject(err);
                }
            } else {
                // 如果直接是一个值,就resolve它
                return resolve(value);
            }
        } else {
            // 如果直接是一个值,就resolve它
            return resolve(value);
        }
    }
    
    // 新建 _Promise 类
    class _Promise {
        constructor(executor) {
            // executor 是一个执行器,进入会立即执行
            // 并传入resolve和reject方法
            try {
                executor(this.resolve, this.reject);
            } catch (error) {
                this.reject(error);
            }
        }
        // 储存状态的变量,初始值是 pending
        status = PENDING;
        // 成功之后的值
        value = null;
        // 失败之后的原因
        reason = null;
        // 存储成功回调函数
        onFulfilledCallbackList = [];
        // 存储失败回调函数
        onRejectedCallbackList = [];
        // 更改成功后的状态
        resolve = value => {
            // 只有状态是等待,才执行状态修改
            if (this.status === PENDING) {
                // 状态修改为成功
                this.status = FULFILLED;
                // 保存成功之后的值
                this.value = value;
                // resolve里面将所有成功的回调拿出来执行
                while (this.onFulfilledCallbackList.length) {
                    // Array.shift() 取出数组第一个元素,然后()调用,shift不是纯函数,取出后,数组将失去该元素,直到数组为空
                    this.onFulfilledCallbackList.shift()(value);
                }
            }
        };
        // 更改失败后的状态
        reject = reason => {
            // 只有状态是等待,才执行状态修改
            if (this.status === PENDING) {
                // 状态成功为失败
                this.status = REJECTED;
                // 保存失败后的原因
                this.reason = reason;
                // resolve里面将所有失败的回调拿出来执行
                while (this.onRejectedCallbackList.length) {
                    this.onRejectedCallbackList.shift()(reason);
                }
            }
        };
        then(onFulfilled, onRejected) {
            const realOnFulfilled = isFunction(onFulfilled) ? onFulfilled : value => value;
            const realOnRejected = isFunction(onRejected)
                ? onRejected
                : reason => {
                      throw reason;
                  };
    
            // 为了链式调用这里直接创建一个 _Promise,并在后面 return 出去
            const subPromise = new _Promise((resolve, reject) => {
                const fulfilledMicrotask = () => {
                    // 创建一个微任务等待 subPromise 完成初始化
                    // 开始采用的queueMicrotask来模拟微任务,但是queueMicrotask是使用promise搞得,这里就有点套娃的柑橘了,所以换成了setTimeout
                    // queueMicrotask(() => {
    
                    // });
                    setTimeout(() => {
                        try {
                            // 获取成功回调函数的执行结果
                            const x = realOnFulfilled(this.value);
                            // 传入 resolvePromise 集中处理
                            resolvePromise(subPromise, x, resolve, reject);
                        } catch (error) {
                            reject(error);
                        }
                    }, 0);
                };
    
                const rejectedMicrotask = () => {
                    // 创建一个微任务等待 subPromise 完成初始化
                    setTimeout(() => {
                        try {
                            // 调用失败回调,并且把原因返回
                            const x = realOnRejected(this.reason);
                            // 传入 resolvePromise 集中处理
                            resolvePromise(subPromise, x, resolve, reject);
                        } catch (error) {
                            reject(error);
                        }
                    }, 0);
                    // queueMicrotask(() => {
    
                    // });
                };
                const statusHandleMap = {
                    [FULFILLED]: fulfilledMicrotask,
                    [REJECTED]: rejectedMicrotask,
                    [PENDING]: () => {
                        this.onFulfilledCallbackList.push(fulfilledMicrotask);
                        this.onRejectedCallbackList.push(rejectedMicrotask);
                    }
                };
                statusHandleMap[this.status]();
                // 判断状态
                // if (this.status === FULFILLED) {
                //     fulfilledMicrotask();
                // } else if (this.status === REJECTED) {
                //     rejectedMicrotask();
                // } else if (this.status === PENDING) {
                //     // 等待
                //     // 因为不知道后面状态的变化情况,所以将成功回调和失败回调存储起来
                //     // 等到执行成功失败函数的时候再传递
                //     this.onFulfilledCallbacks.push(fulfilledMicrotask);
                //     this.onRejectedCallbacks.push(rejectedMicrotask);
                // }
            });
    
            return subPromise;
        }
        // resolve 静态方法
        static resolve(parameter) {
            console.log('value parameter');
            // 如果传入 _Promise 就直接返回
            if (parameter instanceof _Promise) {
                return parameter;
            }
            // 转成常规方式
            return new _Promise(resolve => {
                resolve(parameter);
            });
        }
        // reject 静态方法
        static reject(reason) {
            return new _Promise((resolve, reject) => {
                reject(reason);
            });
        }
    }
    
    // export { _Promise };
    // module.exports = _Promise;
    
    
  • 相关阅读:
    斯特林反演入门
    【清华集训2016】如何优雅地求和
    布隆过滤器
    HBase体系结构
    插入排序
    Hive中的文件存储格式
    HDFS的读写流程
    AQS
    Condition接口
    HashMap源码分析
  • 原文地址:https://www.cnblogs.com/tutao1995/p/15250410.html
Copyright © 2020-2023  润新知