基于Promise/A+规范 浅实现Promise

Promise实现

实现过程中使用到的工具函数

/**

 * 判断传入值是否为一个 对象或者函数
 * @param { * } value 待判断的值
 * @returns { Boolean }
 */
function isObjectOrFunction(value) {
    return (
        !isEqual(value, null) &&
        (judgmentType(value, "object") || judgmentType(value, "function"))
    );
}

/**
 * 判断传入值是否为一个 promise对象 实例
 * @param { * } value 待判断的值
 * @returns { Boolean }
 */
function isPromise(value) {
    return value instanceof myPromise;
}
/**
 * 判断传入值和目标值是否相等
 * @param { * } value 待判断的值
 * @param { * } target 目标值
 * @returns { Boolean }
 */
function isEqual(value, target) {
    return value === target;
}
/**
 * 判断传入值和目标类型是否相等
 * @param { * } value 待判断的值
 * @param { * } type 目标类型
 * @param { Boolean } negation 是否取反判断
 * @returns { Boolean }
 */
function judgmentType(value, type, negation = false) {
    if (negation) {
        return typeof value !== type;
    }
    return typeof value === type;
}

Promise构造函数初始化

  • image.png
    从上图观察可看出,promise实例对象上存在着两个内置属性:PromiseState(状态)、PromiseResult(结果数据)

  • 创建Promise对象时,需要传入执行器函数(executor),执行器函数同步执行。执行器函数内部又包含两个参数resolvereject 。这两个参数(函数)供用户用于修改Promise对象的状态。

  • 在Promise构造函数初始化中,我们需要处理的点:Promise对象的两个内置属性执行器函数(excutor)的同步执行供用户修改Promise对象状态的resolve(),reject()函数

实现

class myPromise {



    // 声明Promise状态

    static PENDING = "pending"; // 待处理(状态)
    static FULFILLED = "fulfilled"; // 已兑现(状态)
    static REJECTED = "rejected"; // 已拒绝(状态)
    constructor(excutor) {
        // 2.1.1 pengding状态的promise对象 其状态可以改变为 fulfilled / rejected 状态
        this.PromiseState = myPromise.PENDING // 初始化 promise状态 为 pending状态
        this.PromiseResult = undefined // 初始化 promise 结果
        try {

            // 执行器函数 excutor的(同步)执行 在其内部用户可调用resolve/reject来改变promise对象状态
            // 这里需要使用bind()函数显式地设置 resolve,reject方法的this指向当前的promise对象, 以便保证resolve/reject的正确执行
            excutor(this.resolve.bind(this), this.reject.bind(this))
        } catch(error) {
          // 捕获执行器函数执行时抛出的报错 显式调用reject 修改当前promise对象的状态 结果值为对应报错信息
            this.reject(error)
        }
    }

     /**
     * 用于修改promise状态 为 fulfilled(已兑现状态)
     * @param { * } result promise对象的结果值(PromiseResult)
     */
    resolve(result) {
         // 2.1.2 fulfilled状态的promise对象 不得改变为任何其他状态 同时必须具有一个结果值
        // promise状态改变:只能从pending状态 改变为 fulfilled / rejected状态,promise状态一经改变 就不可变
        if (!isEqual(this.PromiseState, myPromise.PENDING)) return // 如果 promise对象 不处于 pending状态,直接return 不再执行后续更改状态等相关逻辑
        this.PromiseState = myPromise.FULFILLED // 修改promise对象状态
        this.PromiseResult = result // 为promise对象的结果值 赋值
    }
    /**
     * 用于修改promise状态 为 rejected(已拒绝状态)
     * @param { * } reason promise对象的结果值(PromiseResult)
     */
    reject(reason) {
         // 2.1.3 rejected状态的promise对象 不得改变为任何其他状态 同时必须具有一个结果值(理由/拒因)
        // promise状态改变:只能从pending状态 改变为 fulfilled / rejected状态,promise状态一经改变 就不可变
        if (!isEqual(this.PromiseState, myPromise.PENDING)) return // 如果 promise对象 不处于 pending状态,直接return 不再执行后续更改状态等相关逻辑
        this.PromiseState = myPromise.REJECTED // 修改promise对象状态
        this.PromiseResult = reason // 为promise对象的结果值 赋值
    }
}

Promise对象实例方法 then

 const p = new Promise((resolve, reject) => {
     resolve('success');
 });
 const p1 = new Promise((resolve, reject) => {
     resolve('third success');
 });
 const thenable = () => {}
 thenable.__proto__.then = (onFulfilled, onRejected) => {
     onRejected('failed')
 }
 console.log(1);
 p.then((res) => {
     console.log('then1', res);
     return 'twice success'
 }).then((res) => {
     console.log('then2', res);
    return p1
}).then((res) => {
    console.log('then3', res);
    return {
        then(onFulfilled, onRejected) {
            onFulfilled('fourth success')
        }
    }
}).then((res) => {
    console.log('then4', res);
    return thenable
 }).then((res) => {
    console.log('then5', res);
 }, (err) => {
     console.log(2);
     console.log(err)
 })
 console.log(3);

image.png
从上述代码以及对应输出可以看出then方法的使用可以传入两个 根据Promise实例对象状态执行的回调函数 的可选参数,根据参数回调(onFulfilled/onRejected)执行所返回的值来决定then方法执行(异步执行)所返回的Promise对象(待返Promise对象)状态,同时支持链式调用

  • 根据参数回调执行的返回值类型的不同,作出的状态改变操作也不同。
  1. 返回值为待返Promise对象时,需要抛出报错,修改待返Promise对象状态为rejected,报错信息为结果值。
  2. 返回值为Promise对象时,根据该Promise对象的状态来决定待返Promise对象的状态
  3. 返回值为对象/函数时,检索访问其自定义的then方法,如果访问成功,根据该方法执行的返回值决定待返Promise对象的状态。反之,则修改待返Promise对象状态为fulfilled,返回值为结果值
  4. 返回值不符合上述情况时,则修改待返Promise对象状态为fulfilled,返回值为结果值。
  • 在Promise对象实例 then方法的实现中,我们需要处理的点:接收两个可选参数回调then方法的异步执行返回一个新的Promise对象,支持链式调用根据调用对象的状态执行对应参数回调根据参数回调的返回值决定待返Promise对象的状态

实现

class myPromise {



    // 声明Promise状态

    .......
    
    this.handleFulfilledCb = []
    this.handleRejectedCb = []
    
    constructor(excutor) {.......}
    
    resolve(result) {
        ....
        this.handleFulfilledCb.forEach(cb => cb())
    }
    
    reject(reason) {
        ...
        this.handleRejectedCb.forEach(cb => cb())
    }

    
    then(onFulfilled, onRejected) {
        // 2.2.6 then方法支持链式调用
        // 2.2.6.1 当promise对象状态改变为 fulfilled 时,所有相应 onFulfilled回调根据原始调用顺序执行
        // 2.2.6.2 当promise对象状态改变为 rejected 时,所有相应 onRejected回调根据原始调用顺序执行
        // 声明用于返回的promise对象
        let promiseForReturn = new myPromise((resolve, reject) => {
             // 根据当前promise对象的状态执行对应回调
            switch(this.PromiseState) {
                case myPromise.FULFILLED:
                    // 2.2.4 onFulfilled函数在执行上下文堆栈仅包含平台代码之前,不得调用(即需要异步调用)
                    queueMicrotask(() => {
                        try {
                            // 2.2.1.1 如果onFulfilled不是函数 则必须忽略它
                            if (judgmentType(onFulfilled, 'function', true)) {
                                // 2.2.7.3 如果当前promise对象的状态为fulfilled,且onFulfilled不是一个函数 修改.then方法返回的promise对象的状态为fulfilled,同时继承当前promise对象的结果值
                                // onFulfilled不是函数时,就直接调用resolv() 修改 .then()调用所返回值的状态以及对应结果值
                                resolve(this.PromiseResult)
                            } else {
                                // 2.2.2.1 如果onFulfilled是一个函数 则将当前promise对象的结果值作为第一个参数传入onFulfilled函数中执行
                                // 2.2.2.3 onFulfilled函数只能执行一次,不能被多次调用
                                // 2.2.5 onFulfilled必须作为一个函数调用执行(在严格模式下)
                                // 2.2.7.1 如果onFulfilled的执行 存在返回值,凭此返回值 来决定 .then方法返回的promise对象的状态以及结果值
                                resolvePromise(
                                    promiseForReturn,
                                    onFulfilled(this.PromiseResult),
                                    resolve,
                                    reject
                                )
                            }
                        } catch (error) {
                            // 2.2.7.2 如果onFulfilled函数的执行 抛出报错 则修改.then方法返回的promise对象的状态为rejected,并将报错作为其结果值
                            // 捕获onFulfilled函数执行中 抛出的报错 修改.then方法返回的promise对象状态为rejected,结果值为对应报错信息
                            reject(error)
                        }
                    })
                    break;
                case myPromise.REJECTED:
                    // 2.2.4 onRejected函数在执行上下文堆栈仅包含平台代码之前,不得调用(即需要异步调用)
                    queueMicrotask(() => {
                        try {
                            // 2.2.1.2 如果onRejected不是函数 则必须忽略它
                            if (judgmentType(onRejected, 'function', true)) {
                                // 2.2.7.4 如果当前promise对象的状态为rejected,且onRejected不是一个函数 修改.then方法返回的promise对象的状态为fulfilled,同时继承当前promise对象的结果值(拒因)
                                // onRejected不是函数时,就直接调用resolv() 修改 .then()调用所返回值的状态以及对应结果值
                                reject(this.PromiseResult)
                            } else {
                                // 2.2.3.1 如果onRejected是一个函数 则将当前promise对象的结果值(拒因)作为第一个参数传入onRejected函数中执行
                                // 2.2.3.3 onRejected函数只能执行一次,不能被多次调用
                                // 2.2.5 onRejected必须作为一个函数调用执行(在严格模式下)
                                // 2.2.7.1 如果onRejected的执行 存在返回值,凭此返回值 来决定 .then方法返回的promise对象的状态以及结果值
                                resolvePromise(
                                    promiseForReturn,
                                    onRejected(this.PromiseResult),
                                    resolve,
                                    reject
                                )
                            }
                        } catch (error) {
                            // 2.2.7.2 如果onRejected函数的执行 抛出报错 则修改.then方法返回的promise对象的状态为rejected,并将报错作为其结果值
                            // 捕获onRejected函数执行中 抛出的报错 修改.then方法返回的promise对象状态为rejected,结果值为对应报错信息
                            reject(error)
                        }
                    })
                    break;
                case myPromise.PENDING:
                    // 2.2.2.2 当前promise对象状态为 fulfilled 时,才执行onFulfilled函数,在这之前不执行onFulfilled
                    // 2.2.3.2 当前promise对象状态为 rejected 时,才执行onRejected函数,在这之前不执行onRejected
                    // 当promise对象状态仍处于初始状态时,将对应的回调的相关处理,存储到一个数组中,等到promise对象状态改变为 fulfilled 时,在拿出执行
                    this.handleFulfilledCb.push(() => {
                        queueMicrotask(() => {
                            try {
                                if (judgmentType(onFulfilled, 'function', true)) {
                                    resolve(this.PromiseResult)
                                } else {
                                    resolvePromise(
                                        promiseForReturn,
                                        onFulfilled(this.PromiseResult),
                                        resolve,
                                        reject
                                    )
                                }
                            } catch (error) {
                                reject(error)
                            }
                        })
                    })
                    // 2.2.3.2 当前promise对象状态为 rejected 时,才执行onRejected函数,在这之前不执行onRejected
                    // 当promise对象状态仍处于初始状态时,将对应的回调的相关处理,存储到一个数组中,等到promise对象状态改变为 rejected 时,在拿出执行
                    this.handleRejectedCb.push(() => {
                        queueMicrotask(() => {
                            try {
                                if (judgmentType(onRejected, 'function', true)) {
                                    reject(this.PromiseResult)
                                } else {
                                    resolvePromise(
                                        promiseForReturn,
                                        onRejected(this.PromiseResult),
                                        resolve,
                                        reject
                                    )
                                }
                            } catch (error) {
                                reject(error)
                            }
                        })
                    })
                    break;
            }
                
        })
        // 2.2.7 .then方法调用必须返回一个新的promise对象
        // 返回新的Promise对象
        return promiseForReturn
    }
}
/**

 * 根据 onFulfilled/onRejected 函数执行的返回值,对 .then方法返回的promise对象 作出相应的状态改变操作
 * @param { myPromise } promiseForReturn .then方法返回的 promise对象
 * @param { * } handledResult  onFulfilled/onRejected 函数执行的返回值
 * @param { Function } resolve 修改 .then方法返回的 promise对象 状态为 fulfilled 的方法
 * @param { Function } reject  修改 .then方法返回的 promise对象 状态为 rejected 的方法
 */
function resolvePromise(promiseForReturn, handleResult, resolve, reject) {
    let customThenFn; // 存储自定义的then方法(属性)
    // 2.3.1 如果 onFulfilled/onRejected 函数执行的返回值 指向 .then方法返回的promise对象 抛出对应报错
    if (isEqual(handleResult, promiseForReturn)) {
        // 2.3.2 如果 onFulfilled/onRejected 函数执行的返回值 是一个promise对象 ,根据这个promise对象的状态 执行相应的状态改变变更操作
        // 2.3.2.1 如果该 promise对象(handleResult)处于pending状态,在其状态改变之前 .then方法返回的promise对象始终保持 pending 状态
        // 2.3.2.2 当该 promise对象(handleResult)的状态变更为 fulfilled 时,让 .then方法返回的promise对象 "继承"对应的状态和结果值
        // 2.3.2.3 当该 promise对象(handleResult)的状态变更为 rejected 时,让 .then方法返回的promise对象 "继承"对应的状态和结果值(拒因)
        // 显式的调用 .then方法 完成对应处理
        throw new TypeError("Chaining cycle detected for promise")
    } else if (isPromise(handleResult)) {
        handleResult.then(
            result => resolvePromise(promiseForReturn, result, resolve, reject),
            reason => reject(reason)
        )
    } else if ((isObjectOrFunction) { 
         // 2.3.3 如果返回值是一个对象或者函数
        try {
        // 2.3.3.1 获取返回值的 then 属性
            customThenFn = handleResult.then
        } catch (error) {
            // 2.3.3.2 如果获取 then 属性时, 抛出报错 直接修改 .then方法返回的promise对象为rejected 结果值为对应报错信息
            // 捕获 获取 then 属性时 抛出的报错 修改 .then方法返回的promise对象为rejected 结果值为对应报错信息
            return reject(error)
        }
        if (judfmentType(customThenFn, 'function')) {
            // 2.3.3.3 如果 then属性 是一个函数 就将返回值作为该自定义then函数的 this指向,第一个参数是 类resolve()方法,第二个参数是 类rejecte()方法 传入对应参数 并执行
            // 2.3.3.3.3 如果 类resolve()方法 和 类reject()方法同时被调用 或者 任意一个被多次调用,则第一次调用优先,任何进一步的调用都将被忽略
            let called = false; // 避免多次调用 优先采用首次调用并忽略剩下的调用
            try {
                customThenFn.call(
                    handleResult,
                    (result) => {
                        if (called) return // 如果已经被调用过 直接返回 不作后续处理
                        called = true // 表示已调用
                        // 2.3.3.3.1 如果 类resolve()方法的执行存在返回值,就根据返回值在作出相应处理
                        // 显式地调用resolvepromise() 处理 类resolve方法执行的返回值
                        resolvePromise(promiseForReturn, result, resolve, reject)
                    },
                    (reason) => {
                        if (called) return // 如果已经被调用过 直接返回 不作后续处理
                        called = true // 表示已调用
                        // 2.3.3.3.2 如果 类reject()方法的执行存在返回值(拒因)时,修改.then方法返回的promise对象状态为rejected,结果值为相应的返回值(拒因)
                        reject(reason) 
                        
                    }
                )
            } catch (error) {
                // 2.3.3.3.4 如果自定义 then函数的调用 抛出报错 修改.then方法返回的promise对象状态为rejected,结果值为对应报错信息
                // 2.3.3.3.4.1 如果该报错已被捕获过 则忽略它
                // 2.3.3.3.4.2 反之则捕获报错 并作出相应处理
                if (called) return; // 如果已经被调用过 直接返回 不作后续处理
                called = true // 表示已调用
                reject(error) // 捕获自定义 then函数的调用 抛出的报错 修改 .then方法返回的promise对象为rejected 结果值为对应报错信息
            }
        } else {
            // 2.3.3.4 如果 then属性不是函数 修改.then方法返回的promise对象状态为fulfilled,结果值为返回值
            resolve(handleResult)
        }
    } else {
        // 2.3.4  如果 返回值 既不是对象也不是函数 修改.then方法返回的promise对象状态为fulfilled,结果值为返回值
        resolve(handleResult)
    }
}

完整代码

class myPromise {



    static PENDING = "pending";
    static FULFILLED = "fulfilled";
    static REJECTED = "rejected";
    constructor(excutor) {
        this.PromiseState = myPromise.PENDING;
        this.PromiseResult = undefined;
        this.handleFulfilledCb = [];
        this.handleRejectedCb = [];
        try {

            excutor(this.resolve.bind(this), this.reject.bind(this));
        } catch (error) {
            this.reject(error);
        }
    }
    resolve(result) {
        if (!isEqual(this.PromiseState, myPromise.PENDING)) return;
        this.PromiseState = myPromise.FULFILLED;
        this.PromiseResult = result;
        this.handleFulfilledCb.forEach((cb) => cb());
    }

    reject(reason) {
        if (!isEqual(this.PromiseState, myPromise.PENDING)) return;
        this.PromiseState = myPromise.REJECTED;
        this.PromiseResult = reason;
        this.handleRejectedCb.forEach((cb) => cb());
    }
    then(onFulfilled, onRejected) {
        let promiseForReturn = new myPromise((resolve, reject) => {
            switch (this.PromiseState) {
                case myPromise.FULFILLED:
                    queueMicrotask(() => {
                        try {
                            if (judgmentType(onFulfilled, "function", true)) {
                                resolve(this.PromiseResult);
                            } else {
                                resolvePromise(
                                    promiseForReturn,
                                    onFulfilled(this.PromiseResult),
                                    resolve,
                                    reject
                                );
                            }
                        } catch (error) {
                            reject(error);
                        }
                    });
                    break;
                case myPromise.REJECTED:
                    queueMicrotask(() => {
                        try {
                            if (judgmentType(onRejected, "function", true)) {
                                reject(this.PromiseResult);
                            } else {
                                resolvePromise(
                                    promiseForReturn,
                                    onRejected(this.PromiseResult),
                                    resolve,
                                    reject
                                );
                            }
                        } catch (error) {
                            reject(error);
                        }
                    });
                    break;
                case myPromise.PENDING:
                    this.handleFulfilledCb.push(() => {
                        queueMicrotask(() => {
                            try {
                                if (
                                    judgmentType(onFulfilled, "function", true)
                                ) {
                                    resolve(this.PromiseResult);
                                } else {
                                    resolvePromise(
                                        promiseForReturn,
                                        onFulfilled(this.PromiseResult),
                                        resolve,
                                        reject
                                    );
                                }
                            } catch (error) {
                                reject(error);
                            }
                        });
                    });

                    this.handleRejectedCb.push(() => {
                        queueMicrotask(() => {
                            try {
                                if (
                                    judgmentType(onRejected, "function", true)
                                ) {
                                    reject(this.PromiseResult);
                                } else {
                                    resolvePromise(
                                        promiseForReturn,
                                        onRejected(this.PromiseResult),
                                        resolve,
                                        reject
                                    );
                                }
                            } catch (error) {
                                reject(error);
                            }
                        });
                    });
                    break;
            }
        });

        return promiseForReturn;
    }
}
function resolvePromise(promiseForReturn, handledResult, resolve, reject) {
    let customThenFn;

    if (isEqual(handledResult, promiseForReturn)) {
        throw new TypeError("Chaining cycle detected for promise");
    } else if (isPromise(handledResult)) {
        handledResult.then(
            (result) =>
                resolvePromise(promiseForReturn, result, resolve, reject),
            (reason) => reject(reason)
        );
    } else if (isObjectOrFunction(handledResult)) {
        try {
            customThenFn = handledResult.then;
        } catch (error) {
            return reject(error);
        }
        if (judgmentType(customThenFn, "function")) {
            let called = false;
            try {
                customThenFn.call(
                    handledResult,
                    (result) => {
                        if (called) return;
                        called = true;

                        resolvePromise(
                            promiseForReturn,
                            result,
                            resolve,
                            reject
                        );
                    },
                    (reason) => {
                        if (called) return;
                        called = true;

                        reject(reason);
                    }
                );
            } catch (error) {
                if (called) return;
                called = true;
                reject(error);
            }
        } else {
            resolve(handledResult);
        }
    } else {
        resolve(handledResult);
    }
}
myPromise.deferred = function () {
  let result = {};
  result.promise = new myPromise((resolve, reject) => {
      result.resolve = resolve;
      result.reject = reject;
  });
  return result;
};

module.exports = myPromise;

测试

使用 promises-aplus-tests-refreshed 进行测试 仅测试Promise A+规范中的相关标准

  • 安装
npm i promises-aplus-tests-refreshed
  • 对外暴露myPromise类 并为myPromise类配置deferred属性方法
myPromise.deferred = function () {
    let result = {};
    result.promise = new myPromise((resolve, reject) => {
        result.resolve = resolve;
        result.reject = reject;
    });
    return result;
};

module.exports = myPromise;
  • 设置配置文件(packge.json)
"scripts": {
    "test": "promises-aplus-tests-refreshed 文件路径"
  },
  • 终端运行 npm run test 命令即可开始测试

image.png

Promise对象实例方法 catch

  • Promise实例的catch方法用于注册一个在Promise对象被拒绝时调用的函数,返回一个等效的Promise对象。支持链式调用。实质是Promise.prototype.then(undefined, onRejected)的语法糖

实现

class myPromise {



    .....

    /**

     * .then(undefined, onRejected) 的语法糖
     * @param { Function } onRejected promise调用对象状态为 rejected 所调用的相应回调函数
     * @returns { myPromise }

     */

    catch(onRejected) {
        return this.then(undefined, onRejected)
    }
}

// 测试
            const p1 = new myPromise((resolve, reject) => {
                resolve("成功!");
            });

            p1.then((value) => {
                console.log(value); // "成功!"
                throw new Error("噢,不!");
            })
                .catch((e) => {
                    console.error(e.message); // "噢,不!"
                })
                .then(
                    () => console.log("在 catch 后,调用链恢复了"),
                    () => console.log("因为有了 catch 而不会被触发")
                );
            
            const p2 = new myPromise((resolve, reject) => {
                setTimeout(() => {
                    throw new Error("未捕获的异常!");
                }, 1000);
            });

            p2.catch((e) => {
                console.error(e); // 永远不会被调用
            });
            
            const p3 = new myPromise((resolve, reject) => {
                resolve();
                throw new Error("Silenced Exception!");
            });
            
            p3.catch((e) => {
                console.error(e); // 这里永远不会执行
            });

image.png

Promised对象实例方法 finally

  • Promise实例finally方法用于注册一个在Promise对象状态敲定(兑现/拒绝)时调用的函数,它会立即返回一个等效的Promise对象,支持链式调用。可以用于处理一些无关Promise对象状态的重复操作
  • 注意:所返回的Promise对象与调用对象等效,意味着无论传入的回调函数返回任何内容,待返promise对象依旧”继承”调用对象的相关状态和结果值
  • Promise对象实例方法 finally的实现,我们需要处理的点:无论调用对象处于何种状态,依旧执行参数回调返回一个Promise对象,支持链式调用

实现

class myPromise{
    .....

    /**

     * 无论调用对象处于何种状态,始终调用参数回调
     * @param { Function } onFinally 
     * @returns { myPromise }

     */

    finally(onFinally) {
        if (typeof onFinally !== 'function') {
            onFinally = () => onFinally
        }
        const p =  this.constructor // 获取当前实例的构造函数引用
        // onFinally回调函数的执行 不影响用于返回的promise对象的状态
        // 返回的promise对象状态及结果 继承自this指向的promise对象
        // 使用实例对象上的静态方法resolve() 将onFinally的返回值 或执行 统一转换成一个Promise对象。
        //  p.resolve(onFinally())的处理  用于应对onFinally中存在的异步操作,可以确保onFinally函数的完全执行完毕,再去处理待返Promise对象的状态
        return this.then(
            (result) => p.resolve(onFinally()).then(() => result),
            (reason) => p.resolve(onFinally()).then(() => { thorw reason })
        )
    }

}
// 测试
            function p1() {
                return new myPromise((resolve, reject) => {
                    setTimeout(() => {
                        reject("p1 rejected");
                    }, 1000)
                });
            }
            function p2() {
                return new myPromise((resolve, reject) => {
                    resolve('p2 resolve')
                });
            }
            p2().finally(() => {
                console.log('finally');
            }).then(
                res => console.log(res),
                err => console.log(err)
            )
            p1().finally(() => {
                console.log('finally');
            }).then(
                res => console.log(res),
                err => console.log(err) // 等待一秒后输出
            )

image.png
以上代码中使用到的 Promise静态方法 resolve 在该文章篇幅中尚未实现!

Promise静态方法的实现

参考

手把手一行一行代码教你“手写Promise“,完美通过 Promises/A+ 官方872个测试用例

Promises/A+ (promisesaplus.com)

Promise – JavaScript | MDN (mozilla.org)

第 64 题:模拟实现一个 Promise.finally · Issue #109 · Advanced-Frontend/Daily-Interview-Question · GitHub

完整代码

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYC1I2hR' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片