⚡Promise 介绍及使用✍手写 Promise

465 阅读16分钟

🤖Promise

大纲

1.promise 简介
2.promise 解决的问题
3.promise 使用场景
4.promise API的使用
5.promise 关键问题
6.promise 自定义封装<构造函数-完整代码>
7.promise 自定义封装<class 类-完整代码>


🐽注:

本章是我对 promise 的总结;或有不对的地方,请各位 大佬 指出;感谢!

✍创作不易,如果本章帮助到了您,请给个👍哦;感谢!

🔖1.promise简介:

Promise 是 JavaScript 异步编程的一种解决方案。
它是 ES6 引入的一种原生对象,用来处理异步操作。传统的 JavaScript 异步编程使用的是回调函数,但回调函数容易导致代码可读性差、嵌套层次过深,甚至出现所谓的回调地狱Promise 的出现大大简化了这种情况,使异步代码的书写更加简洁结构更清晰
Promise 的基本原理是,异步操作执行完后,Promise 对象的状态会发生变化,并通知相应的处理函数来处理执行结果。
Promise 有三种状态:pending(等待),fulfilled(成功)和 rejected(失败)。一旦 Promise 进入 fulfilled 或 rejected 状态,就不能再改变状态。


💤2.promise 解决的问题

回调地狱:当多个异步操作需要按顺序执行时,嵌套的回调函数容易让代码变得难以理解和维护,导致所谓的回调地狱。
错误处理:传统的回调函数中,错误的捕获和处理机制复杂,容易出错。而 Promise 提供了统一的 .catch() 方法,可以捕获整个链条中的异常。
控制流程:使用回调函数难以控制异步操作的顺序和依赖,而 Promise 允许以链式方式进行流程控制,显著提升了代码的可读性。

2.1 什么是回调地狱:

是指在 JavaScript 中,使用多个嵌套的回调函数时,代码的可读性和可维护性大幅下降的现象。这种现象通常出现在异步编程中,尤其是处理多个异步操作时,导致代码层层嵌套,看起来像一个“金字塔”,因此得名“回调地狱”。

function step1(callback) {
    setTimeout(() => {
        console.log('Step 1 completed');
        callback();
    }, 1000);
}

function step2(callback) {
    setTimeout(() => {
        console.log('Step 2 completed');
        callback();
    }, 1000);
}

function step3(callback) {
    setTimeout(() => {
        console.log('Step 3 completed');
        callback();
    }, 1000);
}

// 回调地狱示例
step1(() => {
    step2(() => {
        step3(() => {
            console.log('All steps completed');
        });
    });
});

代码解析:
1.每个步骤都是一个异步操作,完成后调用回调函数。
2.为了执行下一个步骤,需要在当前步骤的回调中调用下一个步骤的函数。
3.这导致了代码层层嵌套,难以阅读和维护。

回调地狱的缺点:
1.可读性差: 随着嵌套层级的增加,代码的可读性显著下降,难以理解逻辑。
2.调试困难: 错误通常会在深层嵌套的回调中被捕获,调试和处理错误变得更加复杂。
3.维护性差: 随着代码的增加,修改或重构的难度也增加

2.2 除了 promsie 还可以使用 async / await 来处理:
async function executeSteps() {
    await step1();
    await step2();
    await step3();
    console.log('All steps completed');
}

executeSteps();

💦3.promise 使用场景

网络请求:例如发送 Ajax 请求或使用 fetch API 获取数据,这类请求通常是异步操作,可以通过 Promise 处理请求的成功和失败。
定时任务:在使用 setTimeout 或 setInterval 等异步定时任务时,可以用 Promise 来确保代码按照期望的顺序执行。
文件读取:在浏览器中通过 FileReader 读取文件或在 Node.js 中进行文件系统操作时,往往需要处理异步的读取结果,Promise 可以使代码更加优雅。


👻4.promise_API 及 使用

4.1 Promise.prototype.then()

Promise.prototype.then(onResolve,onRejected);注册两个回调函数,分别处理成功和失败的情况。 then() 方法返回一个新的 Promise 对象,可以实现链式调用。

当 Promise 处于 "fulfilled"(已成功)状态时,p.then 的第一个回调函数(即 onResolve)会被执行。 当 Promise 处于 "rejected"(已失败)状态时,p.then 的第二个回调函数(即 onRejected),或者 p.catch 中的回调函数会被执行。

let p = new Promise((resolve, reject) => {
    resolve('ok');
});

let res = p.then(v => {
    console.log(v);// ok
}, reason => {
    console.log(reason);
});
/*
res 的结果值 取决与 v=>{},reason=>{}的结果值;比如说 v=> new Promise((resolve, reject) =>{resolve('ok1')};那么res的结果值就是 返回的 promise 的结果值 ok1;

Promise.prototype.then 方法的返回值是一个新的 Promise。这个新的 Promise 的结果(状态和值)取决于 then 中回调函数的返回值。如果回调函数返回的是一个新的 Promise,那么 res 的结果会依赖于这个 Promise 的结果;如果回调函数返回的是一个普通值,那么 res 的 Promise 会被 resolve 为这个普通值。
*/
let res1 = p.then(v => new Promise((resolve, reject) => {
    resolve('ok-2');
}))
console.log(res1);
/* 控制台打印 res1的结果:
Promise {<pending>}
[[Prototype]]: Promise
[[PromiseState]]: "fulfilled" // 状态
[[PromiseResult]]: "ok-2"     // 结果值
*/
4.2 Promise.prototype.catch(onRejected)

Promise.prototype.catch(onRejected);只注册失败时的回调函数,等价于 then(null, onRejected)。用于处理 Promise 链条中的错误。

p.catch 等同于 p.then(null, onRejected),专门用来处理 Promise 被拒绝的情况。

let p = new Promise((resolve, reject) => {
    // resolve('ok');
    reject('error');
});

let res = p.catch(reason => {
    console.log(reason);// error
});

// -catch 异常穿透
let p1 = new Promise((resolve, reject) => {
    resolve('ok');
});

let res2 = p1.
    then(v => {
        console.log(111);
    })
    .then(v => {
        console.log(v);//undefined

        throw 'err';
    }) // 这里抛出错误,Promise 链的状态变为 "rejected"
    .then(v => {
        console.log(333);
    }) // 这个 then 不会执行,因为上一个 then 已经进入了 rejected 状态
    .catch(reason => {
        console.log(reason); // 捕获到错误,输出 'err'
    });

/*
    then 返回的都是一个新的Promise;

    第一个 then(p1.then()):
    执行 resolve('ok'),Promise 的状态变为 "fulfilled"。
    第一个 then(v => { console.log(111); }) 被执行,输出 111。
    没有返回值,因此返回 undefined 给下一个 then。

    第二个 then: (then 返回的是一个新的 promise)
    抛出错误 throw 'err',Promise 的状态变为 "rejected"。
    从这一点开始,后续的 then 都会被跳过,直到有 catch 来捕获这个错误。

    第三个 then:
    由于前一个 then 抛出了错误,第三个 then 不会执行,因为 Promise 现在是 "rejected" 状态。
    
    最后的catch:
    这个 catch 捕获了前面抛出的错误 err,输出 'err'。
*/

    console.log(res2, 'res2');
    /* 控制打印 res2 的结果:
    Promise {<pending>}
    [[Prototype]]: Promise
    [[PromiseState]]: "fulfilled"// p1 的状态
    [[PromiseResult]]: undefined // 链式调用都没有返回值,默认返回 undefined,结果值也是 undefined
    */
4.3 Promise.prototype.finally(callback)

无论 Promise 最终状态是 fulfilled 还是 rejected,都会执行 finally 中的回调函数。

let p = new Promise((resolve, reject) => {
    resolve('ok');
});
p.then(v => {
    console.log(v);
}).finally(() => {
    console.log('finally');
});

let p1 = new Promise((resolve, reject) => {
    reject('error');
});
p1.catch(e => {
    console.log(e);
}).finally(() => {
    console.log('finally');
});

/*输出结果:
ok
error
finally
finally
*/
/* 结果说明
p.then(...) 和 p1.catch(...) 都是基于 Promise 的异步行为,这些回调会在所有同步代码执行完毕后,按照事件循环的机制进入微任务队列执行。

因为 p 和 p1 是独立的 Promise,它们的回调顺序相互独立,finally 的执行紧跟着它前面的 then 或 catch,没有干扰。
*/
4.4 Promise.resolve(value)

返回一个状态为 fulfilled 的 Promise,值为 value。

let p1 = Promise.resolve('ok');
console.log(p1, 'p1');// Promise {<fulfilled>: 'ok'}
let p2 = Promise.resolve(new Promise((resolve, reject) => {
    resolve('ok1')
}));
console.log(p2, 'p2');// Promise {<fulfilled>: 'ok1'}

let p3 = Promise.resolve(new Promise((resolve, reject) => {
    reject('error')
}));
console.log(p3, 'p3');
/* 
Promise {<rejected>: 'error'}
Uncaught (in promise) error浏览器报错
*/
/* p3 详细说明

p3 = Promise.resolve(new Promise((resolve, reject) => { reject('error'); })): 

p3 传入了一个新的 Promise,这个 Promise 被 reject,所以 p3 的状态变为 rejected,且会抛出一个未捕获的错误;

p3 的状态是 rejected,由于没有提供 .catch() 或者 .then() 的错误处理回调来捕获这个错误,浏览器会抛出 Uncaught (in promise) 错误。
*/
p3.catch(e => console.log(e))
/* 最终打印结果
Promise {<fulfilled>: 'ok'} 'p1'
Promise {<fulfilled>: 'ok1'} 'p2'
Promise {<rejected>: 'error'} 'p3'
error
*/
4.5 Promise.reject(peason)

返回一个状态为 rejected 的 Promise,理由为 reason

let p1 = Promise.reject('error');
p1.catch(e => {
    console.log(e, 'p1');// error            
});

let p2 = Promise.reject(new Promise((resolve, reject) => {
    resolve('ok')
}));
console.log(p2, 'p2');

p2.catch(e => {
    console.log(e, 'p2.catch');
})
/* 输出结果:
Promise {<rejected>: Promise} 'p2'
error p1 
Promise {<fulfilled>: 'ok'}'p2.catch'
*/
/* 结果说明:
Promise {<rejected>: Promise} 'p2'     👉 p2 是接收了一个promise为参数,promise 是同步的;
error p1                               👉 p1.catch 是异步的;所以 此打印结果不会出现在第一的位置;
Promise {<fulfilled>: 'ok'}'p2.catch'  👉 也是异步的并且排在 p1 的后面执行的;

p1------------------------------------------------------------------------:

p1 是一个通过 Promise.reject('error') 创建的立即被拒绝的 Promise,拒绝原因是 'error'。
p1.catch() 捕获了这个拒绝,并打印 error p1,所以你会看到 error p1 被打印。

p2------------------------------------------------------------------------:

p2 是通过 Promise.reject() 创建的拒绝状态的 Promise,但这次的拒绝原因是一个新的 Promise,即 new Promise((resolve, reject) => { resolve('ok'); })。

Promise.reject() 不会等待这个传递的 Promise 去解析,而是立即拒绝,并将整个 Promise 作为拒绝的原因。因此 p2 的状态是 rejected,其拒绝原因是一个 fulfilled 的 Promise。

当打印 p2 时,会看到 Promise {<rejected>: Promise},表示它是被拒绝的,原因是那个新建的 Promise。

p2.catch() 捕获到了 p2 的拒绝状态,这时 e 就是那个传递给 Promise.reject 的 Promise。

由于这个传递的 Promise 本身是被解析(fulfilled)的,所以当你打印 e 时,你会看到的是一个状态为 fulfilled 的 Promise,结果是 'ok'。

最终输出的是 Promise {<fulfilled>: 'ok'}。
*/
4.6 Promise.all([promise])

接受一个包含多个 Promise 对象的数组或可迭代对象,只有当所有 Promise 都 fulfilled 时,返回的 Promise 状态为 fulfilled,否则一旦有一个 Promise 被 rejected,返回的 Promise 状态为 rejected。

let p1 = Promise.reject('error');
let p2 = Promise.resolve('ok');
let p3 = new Promise((resolve, reject) => {
    resolve('ok_1')
});
let res = Promise.all([p2, p3]);
console.log(res, 'res');
/* 控制台打印结果:
Promise {<pending>}
[[Prototype]]:Promise
[[PromiseState]]:'fulfilled'
[[PromiseResult]]:Array(2)

返回一个状态为 fulfilled 的 Promise,结果值为 Array;
*/
let resThen = res.then(v => {
    console.log(v, 'resThen');// ['ok', 'ok_1'] 'resThen'
})
let res1 = Promise.all([p1, p2, p3]);
console.log(res1, 'res1'); // 控制台报错;原因是没有对 res1的结果进行 .then/.catch
let res2 = res1.then(v => {
    console.log(v, 'res2-V');
}, r => { // 此时的 res1 的状态是 rejected,所以执行 r => {...}
    console.log(r, 'res2-R');// 被捕获了到了
})
4.7 Promise.race([Promise])

和 Promise.all 类似,但是它会在第一个 Promise 结束(无论 fulfilled 还是 rejected)时结束。

let p1 = new Promise((resolve, reject) => {
    resolve('ok_1');// 立即执行
});
let p2 = Promise.reject('error');
let p3 = Promise.resolve('ok');
console.log(p1, p2, p3);

let res = Promise.race([p1, p2, p3]);

res.then(
    v => {
        console.log(v, 'res') // ok_1 res
    },
    reason => {
        console.log(reason, 'res');
    }
);
/* 打印结果:
ok_1 res  
*/
/* 说明
p1,p2,p3 执行顺序问题:

p1-------------------------------------:
p1 是通过 new Promise() 创建的,构造函数会同步执行,因此 resolve('ok_1') 立即执行,但 resolve 本身是异步的,会将回调加入微任务队列中等待执行。
p2-------------------------------------:
p2 是通过 Promise.reject('error') 创建的,Promise.reject() 立即返回一个状态为 rejected 的 Promise,并立即将这个拒绝的原因 'error' 加入微任务队列中。
p3-------------------------------------:
p3 是通过 Promise.resolve('ok') 创建的,它与 Promise.reject() 类似,Promise.resolve() 立即返回一个状态为 fulfilled 的 Promise,并将结果 'ok' 加入微任务队列中
*/
let p4 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('ok_p4') // 宏任务
    })
});
let p5 = new Promise((resolve, reject) => {
    reject('error_p5'); // 立即执行
});
let p6 = new Promise((resolve, reject) => {
    resolve('ok_p6')    // 立即执行
});
let res2 = Promise.race([p4, p5, p6]);
res2.then(v => {
    console.log(v, 'res2');
}, reason => {
    console.log(reason, 'res2');
})

/* 打印结果
error_p5 res2
*/

⛄5.promise 的几个关键问题:

5.1.promise的状态

promise的状态有三种:

1.pending<等待>
2.fulfilled<成功>
3.rejected<失败/拒绝>

5.2.可以改变promise状态的三种方式

1.promise的状态由 pending 变为 fulfilled
2.promise的状态由 pending 变为 rejected
3.throw 抛出错误 promise 的状态由 pending 变为 rejected


Promise 的状态是 不可逆 的,一旦 Promise 的状态由 pending 变为 fulfilled/rejectedPromise的状态就不可在改变。这确保了异步操作的结果的一致且可信性;

5.3.promise 同步异步问题
let p = new Promise((resolve, reject) => {
    resolve('ok');
    console.log('111');
});

p.then(v => console.log('222'));

setTimeout(() => {
    console.log('444');
});

console.log('333');

/* 输出结果:
'111' —— Promise 构造函数中的同步代码
'333' —— 同步代码
'222' —— then 中的回调,微任务
'444' —— setTimeout 回调,宏任务
*/

根据输出结果得知:

1. Promise 的构造函数是同步执行的。也就是说,当你创建一个 Promise 实例时,传递给它的执行器函数(executor,即 resolve 和 reject 所在的函数)会立即执行。

executor 等同Promise 接收的 (resolve, reject) => {}

2. 虽然 Promise 构造函数是同步执行的,但 then、catch 等回调函数是异步执行的。它们会在当前的执行栈清空之后(即所有同步任务执行完毕后),被推入微任务队列(microtask queue)中等待执行。

5.4.错误传播机制

Promise 链条中,如果某一个环节抛出错误,错误会沿着链条向下传播,直到被捕获为止。未捕获的错误会导致整个链条失败,但可以通过 .catch() 进行统一的错误处理。

证明:

不加 catch 进行捕获错误;

let p = new Promise((resolve, reject) => {
    resolve('ok');
});
/*
p.then() 返回一个新的 Promise,其状态为 fulfilled,且结果是 上一个 promise返回的结果;
*/

//不写任何人东西,返回的 Promise 是成功状态且 结果值为 'ok';并且结果会传递给下一个 then
p.then()
    .then(value => {
        console.log('仔仔💓'); 
        throw new Error('这里抛出了一个 🐖');  
    })
    .then(value => {
        console.log('崽崽💖');  
    })
    // .catch(error => {
    //     console.log('error:', error.message); 
    // })
    .then(() => {
        console.log('代码走到了这里'); 
    });
    
    /* 控制台打印结果
    仔仔💓
    <Error>:Uncaught (in promise) Error: 这里抛出了一个 🐖(控制台直接报错)
    */
    

加上 catch 捕获错误:

let p = new Promise((resolve, reject) => {
    resolve('ok');
});
/*
p.then() 返回一个新的 Promise,其状态为 fulfilled,且结果是 上一个 promise返回的结果;
*/

//不写任何人东西,返回的 Promise 是成功状态且 结果值为 'ok';并且结果会传递给下一个 then
p.then()
    .then(value => {
        console.log('仔仔💓');  // 仔仔💓'
        throw new Error('这里抛出了一个 🐖');  
    })
    .then(value => {
        console.log('崽崽💖'); 
    })
    .catch(error => {
        console.log('error:', error.message); 
    })
    .then(() => {
        console.log('代码走到了这里'); 
    });

    /* 控制台打印结果
    仔仔💓
    error: 这里抛出了一个 🐖
    代码走到了这里
    */
    

释:

let p = new Promise((resolve, reject) => {
    resolve('ok');
});
/*
p.then() 返回一个新的 Promise,其状态为 fulfilled,且结果是 上一个 promise返回的结果;
*/

//不写任何人东西,返回的 Promise 是成功状态且 结果值为 'ok';并且结果会传递给下一个 then
p.then()
    .then(value => {
        console.log('仔仔💓');  //控制台输出: 仔仔💓'
        throw new Error('这里抛出了一个 🐖');  // 在此处抛出错误
    })
    .then(value => {
        console.log('崽崽💖');  // 不会执行,因为上一个环节抛出了错误
    })
    .catch(error => {
        console.log('error:', error.message);  // 捕获并输出错误信息
    })
    .then(() => {
        console.log('代码走到了这里');  // 依然可以继续执行
    });
    

🎈6.promise 封装<构造函数-完整代码>

function Promise(executor) {
    // 初始化状态
    this.PromiseState = 'pending';
    // 初始化结果值
    this.PromiseResult = undefined;
    // (异步时)保存回调函数
    this.callbacks = [];
    /**
     * 状态、结果值、保存的回调函数 统一处理函数
     * @param {String} state 
     * @param {any} data 
     */
    const handlerFn = (state, data) => {
        // promise 的状态只能改变一次;
        if (this.PromiseState !== 'pending') return;

        this.PromiseState = state;
        this.PromiseResult = data;

        // 微任务
        queueMicrotask(() => {
            this.callbacks.forEach(callback => {
                // 根据异步回来的状态 执行相应的函数
                if (state === 'fulfilled') callback.onResolve(data);
                if (state === 'rejected') callback.onRejected(data);
            })
        })
    };
    /**
     * 状态成功所调用的函数
     * @param {any} data 
     */
    const resolve = data => handlerFn('fulfilled', data);
    /**
     * 状态失败所调用的函数
     * @param {any} data 
     */
    const reject = data => handlerFn('rejected', data);

    // 使用 try catch 捕获错误;
    try {
        // 未捕获到错误则 执行器工作
        executor(resolve, reject);
    } catch (error) {
        // 捕获到错误 promise的状态则为失败/拒绝
        reject(error);
    }
};
Promise.prototype.then = function (onResolve, onRejected) {
    // 为 .then 补齐参数;
    if (typeof onResolve !== 'function') onResolve = v => v;
    // 实现 .catch 异常穿透的核心
    if (typeof onRejected !== 'function') onRejected = r => { throw r };
    // 返回一个 Promise
    return new Promise((resolve, reject) => {
        /**
         * 统一处理函数
         * @param {Function} callback 
         * @param {any} value 
         * @param {Function} resolve 
         * @param {Function} reject 
         */
        const handlerPromiseChange = (callback) => {
            try {
                // 结果值
                let result = callback(this.PromiseResult);
                // 结果值是否为一个 promise
                if (result instanceof Promise) {
                    result.then(v => {
                        resolve(v);
                    }, r => {
                        reject(r);
                    });
                } else {
                    // 否 执行 resolve 设置状态及结果值
                    resolve(result)
                }
            } catch (error) {
                // 捕获到错误 则 promise 的状态为 rejected/失败/拒绝 值为error
                reject(error);
            }
        };
        // 异步
        if (this.PromiseState === 'pending') {
            // 异步时 保存回调函数;当Promise的状态改变之后再去执行对应的回调函数
            this.callbacks.push({
                onResolve: () => handlerPromiseChange(onResolve),
                onRejected: () => handlerPromiseChange(onRejected),
            })
        };
        // 同步 成功
        if (this.PromiseState === 'fulfilled') {
            // 微任务
            queueMicrotask(() => {
                handlerPromiseChange(onResolve);
            })
        };
        // 同步 失败/拒绝
        if (this.PromiseState === 'rejected') {
            // 微任务
            queueMicrotask(() => {
                handlerPromiseChange(onRejected);
            })
        };
    });
};
Promise.prototype.catch = function (onRejected) {
    // 返回一个 promise,这里直接调用 then方法,并且值传递 失败/拒绝的处理 回调函数
    return this.then(undefined, onRejected);
};
Promise.prototype.finally = function (callback) {
    // finally 方法正确地在 then 和 catch 之后执行
    return this.then(
        v => Promise.resolve(callback()).then(() => v),
        r => Promise.resolve(callback()).then(() => { throw r; })
    );
}
Promise.resolve = function (value) {
    //返回promise对象
    return new Promise((resolve, reject) => {
        if (value instanceof Promise) {
            value.then(v => {
                resolve(v);
            }, r => {
                reject(r);
            })
        } else {
            //状态设置为成功
            resolve(value);
        }
    });
};
Promise.reject = function (reason) {
    /*
    返回一个状态为失败的 promise
    */
    return new Promise((_, reject) => reject(reason));
};
Promise.race = function (promises) {
    // 如果 promises 不是一个数组,报错提示;
    if (!Array.isArray(promises)) throw TypeError('promises must be an Array');
    // 返回一个 Promise
    return new Promise((resolve, reject) => {
        // 遍历 promises
        promises.forEach(item => {
            item.then(v=>{resolve(v)},r=>{reject(r)});
        })
    })
};
Promise.all = function (promises) {
    // 如果 promises 不是一个数组,报错提示;
    if (!Array.isArray(promises)) throw TypeError('promises must be an Array');
    // 返回一个Promise
    return new Promise((resolve, reject) => {
        // 保存 promises数组 的每一项 promise成功的结果值;
        let newArr = new Array(promises.length);
        // 计算循环次数
        let count = 0;
        // 遍历 promises
        promises.forEach((item, index) => {
            item.then(v => {
                newArr[index] = v;
                count++;
                if (count === promises.length) {
                    resolve(newArr);
                }
            }, r => {
                reject(r)
            })
        })
    })
};

🛸 7.Promise自定义封装<class 类-完整代码>

class Promise {
    constructor(executor) {
        // 初始化状态
        this.PromiseState = 'pending';
        // 初始化结果值
        this.PromiseResult = undefined;
        // (异步时)保存回调函数
        this.callbacks = [];

        /**
         * 状态、结果值、保存的回调函数 统一处理函数
         * @param {String} state
         * @param {any} data
         */
        const handlerFn = (state, data) => {
            // promise 的状态只能改变一次;
            if (this.PromiseState !== 'pending') return;

            this.PromiseState = state;
            this.PromiseResult = data;

            // 微任务
            queueMicrotask(() => {
                this.callbacks.forEach(callback => {
                    // 根据异步回来的状态 执行相应的函数
                    if (state === 'fulfilled') callback.onResolve(data);
                    if (state === 'rejected') callback.onRejected(data);
                });
            });
        };

        /**
         * 状态成功所调用的函数
         * @param {any} data
         */
        const resolve = (data) => handlerFn('fulfilled', data);

        /**
         * 状态失败所调用的函数
         * @param {any} data
         */
        const reject = (data) => handlerFn('rejected', data);

        // 使用 try catch 捕获错误;
        try {
            // 未捕获到错误则 执行器工作
            executor(resolve, reject);
        } catch (error) {
            // 捕获到错误 promise的状态则为失败/拒绝
            reject(error);
        }
    }

    then(onResolve, onRejected) {
        // 为 .then 补齐参数;
        if (typeof onResolve !== 'function') onResolve = (v) => v;
        // 实现 .catch 异常穿透的核心
        if (typeof onRejected !== 'function') onRejected = (r) => { throw r; };

        // 返回一个 Promise
        return new Promise((resolve, reject) => {
            /**
             * 统一处理函数
             * @param {Function} callback
             */
            const handlerPromiseChange = (callback) => {
                try {
                    // 结果值
                    let result = callback(this.PromiseResult);
                    // 结果值是否为一个 promise
                    if (result instanceof Promise) {
                        result.then(resolve, reject);
                    } else {
                        // 否 执行 resolve 设置状态及结果值
                        resolve(result);
                    }
                } catch (error) {
                    // 捕获到错误 则 promise 的状态为 rejected/失败/拒绝 值为error
                    reject(error);
                }
            };

            // 异步
            if (this.PromiseState === 'pending') {
                // 异步时 保存回调函数;当Promise的状态改变之后再去执行对应的回调函数
                this.callbacks.push({
                    onResolve: () => handlerPromiseChange(onResolve),
                    onRejected: () => handlerPromiseChange(onRejected),
                });
            }

            // 同步 成功
            if (this.PromiseState === 'fulfilled') {
                // 微任务
                queueMicrotask(() => {
                    handlerPromiseChange(onResolve);
                });
            }

            // 同步 失败/拒绝
            if (this.PromiseState === 'rejected') {
                // 微任务
                queueMicrotask(() => {
                    handlerPromiseChange(onRejected);
                });
            }
        });
    }

    catch(onRejected) {
        // 返回一个 promise,这里直接调用 then方法,并且值传递 失败/拒绝的处理 回调函数
        return this.then(undefined, onRejected);
    }

    finally(callback) {
        // finally 方法正确地在 then 和 catch 之后执行
        return this.then(
            (v) => Promise.resolve(callback()).then(() => v),
            (r) => Promise.resolve(callback()).then(() => { throw r; })
        );
    }

    static resolve(value) {
        //返回promise对象
        return new Promise((resolve, reject) => {
            if (value instanceof Promise) {
                value.then(resolve, reject);
            } else {
                //状态设置为成功
                resolve(value);
            }
        });
    }

    static reject(reason) {
        // 返回一个状态为失败的 promise
        return new Promise((_, reject) => reject(reason));
    }

    static race(promises) {
        // 如果 promises 不是一个数组,报错提示;
        if (!Array.isArray(promises)) throw TypeError('promises must be an Array');
        // 返回一个 Promise
        return new Promise((resolve, reject) => {
            // 遍历 promises
            promises.forEach((item) => {
                item.then(resolve, reject);
            });
        });
    }

    static all(promises) {
        // 如果 promises 不是一个数组,报错提示;
        if (!Array.isArray(promises)) throw TypeError('promises must be an Array');
        // 返回一个Promise
        return new Promise((resolve, reject) => {
            // 保存 promises数组 的每一项 promise成功的结果值;
            let newArr = new Array(promises.length);
            // 计算循环次数
            let count = 0;

            // 遍历 promises
            promises.forEach((item, index) => {
                item.then((v) => {
                    newArr[index] = v;
                    count++;
                    if (count === promises.length) {
                        resolve(newArr);
                    }
                }, reject);
            });
        });
    }
}