JavaScript 一步步手写实现 Promise

94 阅读16分钟

一、Promie 类基本核心逻辑实现

const p = new Promise((resolve, reject) => {
  resolve('成功')
});
p.then((data) => {
  console.log('resolved',data);
},(err) => {
  console.log('rejected',err);
}); 

以上是 Promise 的基本使用,可以得知

  1. Promise 就是一个类,在执行这个类的时候,需要传递一个执行器进去,并且执行器会立即执行
  2. Promise 中有三种状态,分别为成功 fulfilled 失败 rejected 等待 pending
  3. Promise 的状态默认 pending,是只能被修改一次,一旦被修改就不可修改,只能从 pending 改成 fulfilled,或者是从 pending 改成 rejected
  4. 传递给执行器的两个方法 resolve 和 reject 函数都是用来更改状态的,resolve 把状态变成 fulfilled,reject 把状态变成 rejected
  5. then 方法内部做的事情就判断状态,如果状态是成功,调用成功的回调函数,如果状态是失败,调用失败回调函数,then方法是被定义在原型对象中的,then 成功回调有一个参数,表示成功之后的值,then 失败回调有一个参数,表示失败后的原因
const PENDING = 'pending'; // 等待
const FULFILLED = 'fulfilled'; // 成功
const REJECTED = 'rejected'; // 失败

class MyPromise {

    // 接收执行器,并且立即执行
    constructor(executor) {
        try {
            executor(this.resolve, this.reject)
        } catch (e) {
            // 如果执行器报错,则执行 reject
            this.reject(e);
        }
    }

    // promsie 状态 ,默认值是 pending
    status = PENDING
    // 成功之后的值
    value = undefined
    // 失败后的原因
    reason = undefined

    resolve = (value) => {
        // 如果状态不是等待 阻止程序向下执行
        if (this.status !== PENDING) return;
        // 将状态更改为 fulfilled
        this.status = FULFILLED
        // 保存成功之后的值
        this.value = value
    }

    reject = (reason) => {
        // 如果状态不是等待 阻止程序向下执行
        if (this.status !== PENDING) return;
        // 将状态更改为 rejected
        this.status = REJECTED;
        // 保存失败后的原因
        this.reason = reason
    }

    then(successCallback, failCallback) {
        // 判断状态,如果状态为成功,调用 successCallback,如果状态为失败,调用 failCallback
        if (this.status === FULFILLED) {
            successCallback(this.value)
        }
        else if (this.status === REJECTED) {
            failCallback(this.reason)
        }
    }
}

二、在 Promie 类中加入对异步逻辑的处理

const p = new Promise((resolve, reject) => {
  setTimeout(function () {
       resolve('成功')
   }, 2000)
});
p.then((data) => {
  console.log('resolved',data);
},(err) => {
  console.log('rejected',err);
}); 

因为上述代码中执行器中的代码是异步执行的,没有立即调用 resolve,导致 then 方法执行的时候状态还是 promise 的状态还是 pending,所以我们要先把 then 方法中成功和失败的回调保存起来,在执行器执行 resolve 或者 reject 的时候,判断是否存在相对应的回调函数,如果有就执行

const PENDING = 'pending'; // 等待
const FULFILLED = 'fulfilled'; // 成功
const REJECTED = 'rejected'; // 失败

class MyPromise {

    // 接收执行器,并且立即执行
    constructor(executor) {
        try {
            executor(this.resolve, this.reject)
        } catch (e) {
            // 如果执行器报错,则执行 reject
            this.reject(e);
        }
    }

    // promsie 状态 ,默认值是 pending
    status = PENDING
    // 成功之后的值
    value = undefined
    // 失败后的原因
    reason = undefined
    // 成功回调
    successCallback = undefined;
    // 失败回调
    failCallback = undefined;

    resolve = (value) => {
        // 如果状态不是等待 阻止程序向下执行
        if (this.status !== PENDING) return;
        // 将状态更改为 fulfilled
        this.status = FULFILLED
        // 保存成功之后的值
        this.value = value
        // 判断成功回调是否回调,如果存在就调用
        this.successCallback && this.successCallback(value)
    }

    reject = (reason) => {
        // 如果状态不是等待 阻止程序向下执行
        if (this.status !== PENDING) return;
        // 将状态更改为 rejected
        this.status = REJECTED;
        // 保存失败后的原因
        this.reason = reason
        // 判断失败回调是否回调,如果存在就调用
        this.failCallback && this.failCallback(reason)
    }

    then(successCallback, failCallback) {
        // 判断状态,如果状态为成功,调用 successCallback,如果状态为失败,调用 failCallback
        if (this.status === FULFILLED) {
            successCallback(this.value)
        }
        else if (this.status === REJECTED) {
            failCallback(this.reason)
        }
        else {
            // 当前状态为等待
            // 将成功回调和失败回调存储起来
            this.successCallback = successCallback
            this.failCallback = failCallback
        }
    }
}

三、实现 then 方法多次调用添加多个处理函数

const p = new Promise((resolve, reject) => {
  setTimeout(function () {
       resolve('成功')
   }, 2000)
});
p.then(value => { console.log('1', value) })
p.then(value => { console.log('1', value) })
p.then(value => { console.log('1', value) })

上述代码中,then 方法被调用了三次,有三个成功的回调函数,所以说 promise 必须用数组来保存成功和失败的回调,等到 resolve 或者 reject,再将数组中的回调函数循环执行

const PENDING = 'pending'; // 等待
const FULFILLED = 'fulfilled'; // 成功
const REJECTED = 'rejected'; // 失败

class MyPromise {

    // 接收执行器,并且立即执行
    constructor(executor) {
        try {
            executor(this.resolve, this.reject)
        } catch (e) {
            // 如果执行器报错,则执行 reject
            this.reject(e);
        }
    }

    // promsie 状态 ,默认值是 pending
    status = PENDING
    // 成功之后的值
    value = undefined
    // 失败后的原因
    reason = undefined
    // 成功回调
    successCallback = [];
    // 失败回调
    failCallback = [];

    resolve = (value) => {
        // 如果状态不是等待 阻止程序向下执行
        if (this.status !== PENDING) return;
        // 将状态更改为 fulfilled
        this.status = FULFILLED
        // 保存成功之后的值
        this.value = value
        // 判断成功回调是否回调,如果存在就依次调用
        while (this.successCallback.length) {
            // 从前往后执行
            this.successCallback.shift()(value)
        }
    }

    reject = (reason) => {
        // 如果状态不是等待 阻止程序向下执行
        if (this.status !== PENDING) return;
        // 将状态更改为 rejected
        this.status = REJECTED;
        // 保存失败后的原因
        this.reason = reason
        // 判断失败回调是否回调,如果存在就依次调用
        while (this.failCallback.length) {
            // 从前往后执行
            this.failCallback.shift()(reason)
        }
    }

    then(successCallback, failCallback) {
        // 判断状态,如果状态为成功,调用 successCallback,如果状态为失败,调用 failCallback
        if (this.status === FULFILLED) {
            successCallback(this.value)
        }
        else if (this.status === REJECTED) {
            failCallback(this.reason)
        }
        else {
            // 当前状态为等待
            // 将成功回调和失败回调存储起来
            this.successCallback.push(successCallback)
            this.failCallback.push(failCallback)
        }
    }
}

四、实现 then 方法的链式调用

const p = new Promise((resolve, reject) => {
  setTimeout(function () {
       resolve('成功')
   }, 2000)
});
p.then(value => {
  console.log(value)
  return 100
}).then(value => {
  console.log(value) // 100
})

在上述代码中 then 方法被链式调用了,也就是说 then 方法返回的是一个 Promise 的实例对象,并且下一个 then 方法拿到的值,是上一个 then 方法回调函数的返回值,所以说在执行 then 方法的时候必须 new 一个 Promise 的实例对象,并且将判断逻辑写到这个这个 promise 对象的执行器中,如果上一个 promise 对象的状态为 fulfilled ,则获取上一个 promise 对象成功回调的返回值,传给下一个 then 的回调函数

const PENDING = 'pending'; // 等待
const FULFILLED = 'fulfilled'; // 成功
const REJECTED = 'rejected'; // 失败

class MyPromise {

    // 接收执行器,并且立即执行
    constructor(executor) {
        try {
            executor(this.resolve, this.reject)
        } catch (e) {
            // 如果执行器报错,则执行 reject
            this.reject(e);
        }
    }

    // promsie 状态 ,默认值是 pending
    status = PENDING
    // 成功之后的值
    value = undefined
    // 失败后的原因
    reason = undefined
    // 成功回调
    successCallback = [];
    // 失败回调
    failCallback = [];

    resolve = (value) => {
        // 如果状态不是等待 阻止程序向下执行
        if (this.status !== PENDING) return;
        // 将状态更改为 fulfilled
        this.status = FULFILLED
        // 保存成功之后的值
        this.value = value
        // 判断成功回调是否回调,如果存在就依次调用
        while (this.successCallback.length) {
            // 从前往后执行
            this.successCallback.shift()(value)
        }
    }

    reject = (reason) => {
        // 如果状态不是等待 阻止程序向下执行
        if (this.status !== PENDING) return;
        // 将状态更改为 rejected
        this.status = REJECTED;
        // 保存失败后的原因
        this.reason = reason
        // 判断失败回调是否回调,如果存在就依次调用
        while (this.failCallback.length) {
            // 从前往后执行
            this.failCallback.shift()(reason)
        }
    }

    then(successCallback, failCallback) {
        // 创建一个 promise 对象
        let promise2 = new MyPromise((resolve, reject) => {
            // 判断状态,如果状态为成功,调用 successCallback,如果状态为失败,调用 failCallback
            if (this.status === FULFILLED) {
                // 获取回调函数的返回值
                let x = successCallback(this.value)
                // 将回调函数的值传递给下一个 then 的回调函数
                resolve(x)
            }
            else if (this.status === REJECTED) {
                failCallback(this.reason)
            }
            else {
                // 当前状态为等待
                // 将成功回调和失败回调存储起来
                this.successCallback.push(successCallback)
                this.failCallback.push(failCallback)
            }
        })
        return promise2
    }
}
const p = new Promise((resolve, reject) => {
  setTimeout(function () {
       resolve('成功')
   }, 2000)
});
p.then(value => {
  console.log(value)
   return new Promise((resolve, reject) => { resolve('100') })
}).then(value => {
  console.log(value) // 100
})

上述代码中,第一次 then 方法回调函数返回的不是一个普通值,而是一个 promise 对象,所以就得先去查看这个 promise 对象的状态,如果状态是成功的话,就调用这个 promise 对象的 resolve 方法,把这个成功的状态传递给下一个 promise 对象,如果状态是失败的,就得调用它的 reject 方法,把失败的状态传递给下一个 promise 对象,这里我们就定义一个方法来判断第一次 then 方法中回调函数的返回值究竟是 promise 对象还是普通值

const PENDING = 'pending'; // 等待
const FULFILLED = 'fulfilled'; // 成功
const REJECTED = 'rejected'; // 失败

class MyPromise {

    // 接收执行器,并且立即执行
    constructor(executor) {
        try {
            executor(this.resolve, this.reject)
        } catch (e) {
            // 如果执行器报错,则执行 reject
            this.reject(e);
        }
    }

    // promsie 状态 ,默认值是 pending
    status = PENDING
    // 成功之后的值
    value = undefined
    // 失败后的原因
    reason = undefined
    // 成功回调
    successCallback = [];
    // 失败回调
    failCallback = [];

    resolve = (value) => {
        // 如果状态不是等待 阻止程序向下执行
        if (this.status !== PENDING) return;
        // 将状态更改为 fulfilled
        this.status = FULFILLED
        // 保存成功之后的值
        this.value = value
        // 判断成功回调是否回调,如果存在就依次调用
        while (this.successCallback.length) {
            // 从前往后执行
            this.successCallback.shift()(value)
        }
    }

    reject = (reason) => {
        // 如果状态不是等待 阻止程序向下执行
        if (this.status !== PENDING) return;
        // 将状态更改为 rejected
        this.status = REJECTED;
        // 保存失败后的原因
        this.reason = reason
        // 判断失败回调是否回调,如果存在就依次调用
        while (this.failCallback.length) {
            // 从前往后执行
            this.failCallback.shift()(reason)
        }
    }

    then(successCallback, failCallback) {
        // 创建一个 promise 对象
        let promise2 = new MyPromise((resolve, reject) => {
            // 判断状态,如果状态为成功,调用 successCallback,如果状态为失败,调用 failCallback
            if (this.status === FULFILLED) {
                // 获取回调函数的返回值
                let x = successCallback(this.value)

                // 判断 x 的值是普通值还是 promise 对象
                // 如果是普通值,直接调用 resolve 
                // 如果是 promise 对象 查看 promsie 对象返回的结果 
                // 再根据 promise 对象返回的结果 决定调用 resolve 还是调用 reject
                resolvePromise(x, resolve, reject)
            }
            else if (this.status === REJECTED) {
                failCallback(this.reason)
            }
            else {
                // 当前状态为等待
                // 将成功回调和失败回调存储起来
                this.successCallback.push(successCallback)
                this.failCallback.push(failCallback)
            }
        })
        return promise2
    }
}
function resolvePromise(x, resolve, reject) {
    if (x instanceof MyPromise) {
        // promise 对象
        // x.then(value => resolve(value), reason => reject(reason)); 等价于下面代码
        x.then(resolve, reject);
    } else {
        // 普通值
        resolve(x);
    }
}

五、实现 then 方法链式调用识别 Promie 对象自返回情况

const p = new Promise((resolve, reject) => {
  setTimeout(function () {
       resolve('成功')
   }, 2000)
});
const p1 = p.then(value => {
  console.log(value)
  return p1
})
p1.then(value => {
  console.log(value)
})

上述代码中出现了在 then 方法的回调函数中返回了当前这个 then 方法返回的 promise 对象的情况,出现这种情况会导致浏览器死机的,因为如果在当前 then 方法的回调函数中返回的 promise 对象和 then 方法返回的 promise 对象一样,就会导致 promise 对象的循环调用,所以就得做判断,将当前要返回的 promise 对象传进去,和将要执行的 promise 对象做对比,如果出现自调用的情况,就抛出异常

const PENDING = 'pending'; // 等待
const FULFILLED = 'fulfilled'; // 成功
const REJECTED = 'rejected'; // 失败

class MyPromise {

    // 接收执行器,并且立即执行
    constructor(executor) {
        try {
            executor(this.resolve, this.reject)
        } catch (e) {
            // 如果执行器报错,则执行 reject
            this.reject(e);
        }
    }

    // promsie 状态 ,默认值是 pending
    status = PENDING
    // 成功之后的值
    value = undefined
    // 失败后的原因
    reason = undefined
    // 成功回调
    successCallback = [];
    // 失败回调
    failCallback = [];

    resolve = (value) => {
        // 如果状态不是等待 阻止程序向下执行
        if (this.status !== PENDING) return;
        // 将状态更改为 fulfilled
        this.status = FULFILLED
        // 保存成功之后的值
        this.value = value
        // 判断成功回调是否回调,如果存在就依次调用
        while (this.successCallback.length) {
            // 从前往后执行
            this.successCallback.shift()(value)
        }
    }

    reject = (reason) => {
        // 如果状态不是等待 阻止程序向下执行
        if (this.status !== PENDING) return;
        // 将状态更改为 rejected
        this.status = REJECTED;
        // 保存失败后的原因
        this.reason = reason
        // 判断失败回调是否回调,如果存在就依次调用
        while (this.failCallback.length) {
            // 从前往后执行
            this.failCallback.shift()(reason)
        }
    }

    then(successCallback, failCallback) {
        // 创建一个 promise 对象
        let promise2 = new MyPromise((resolve, reject) => {
            // 判断状态,如果状态为成功,调用 successCallback,如果状态为失败,调用 failCallback
            if (this.status === FULFILLED) {
                setTimeout(() => {
                    try {
                        // 获取回调函数的返回值
                        let x = failCallback(this.reason);

                        // 判断 x 的值是普通值还是promise对象
                        // 如果是普通值 直接调用resolve 
                        // 如果是promise对象 查看promsie对象返回的结果 
                        // 再根据promise对象返回的结果 决定调用resolve 还是调用reject

                        // promsie2 是在 new MyPromise 执行完成之后才有的,所以得把这段代码写出异步代码,使用 setTimeout
                        resolvePromise(promsie2, x, resolve, reject)
                    } catch (e) {
                        reject(e);
                    }
                }, 0)
            }
            else if (this.status === REJECTED) {
                failCallback(this.reason)
            }
            else {
                // 当前状态为等待
                // 将成功回调和失败回调存储起来
                this.successCallback.push(successCallback)
                this.failCallback.push(failCallback)
            }
        })
        return promise2
    }
}
function resolvePromise(promsie2, x, resolve, reject) {
    // 如果 then 中回调函数返回的 promise 对象和 then 返回的 promise 对象一样,就抛出异常
    if (promsie2 === x) {
        return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
    }
    if (x instanceof MyPromise) {
        // promise 对象
        // x.then(value => resolve(value), reason => reject(reason)); 等价于下面代码
        x.then(resolve, reject);
    } else {
        // 普通值
        resolve(x);
    }
}

六、then 链式调用失败和等待状态处理

const PENDING = 'pending'; // 等待
const FULFILLED = 'fulfilled'; // 成功
const REJECTED = 'rejected'; // 失败

class MyPromise {

    // 接收执行器,并且立即执行
    constructor(executor) {
        try {
            executor(this.resolve, this.reject)
        } catch (e) {
            // 如果执行器报错,则执行 reject
            this.reject(e);
        }
    }

    // promsie 状态 ,默认值是 pending
    status = PENDING
    // 成功之后的值
    value = undefined
    // 失败后的原因
    reason = undefined
    // 成功回调
    successCallback = [];
    // 失败回调
    failCallback = [];

    resolve = (value) => {
        // 如果状态不是等待 阻止程序向下执行
        if (this.status !== PENDING) return;
        // 将状态更改为 fulfilled
        this.status = FULFILLED
        // 保存成功之后的值
        this.value = value
        // 判断成功回调是否回调,如果存在就依次调用
        while (this.successCallback.length) {
            // 从前往后执行
            this.successCallback.shift()()
        }
    }

    reject = (reason) => {
        // 如果状态不是等待 阻止程序向下执行
        if (this.status !== PENDING) return;
        // 将状态更改为 rejected
        this.status = REJECTED;
        // 保存失败后的原因
        this.reason = reason
        // 判断失败回调是否回调,如果存在就依次调用
        while (this.failCallback.length) {
            // 从前往后执行
            this.failCallback.shift()()
        }
    }

    then(successCallback, failCallback) {
        // 创建一个 promise 对象
        let promise2 = new MyPromise((resolve, reject) => {
            // 判断状态,如果状态为成功,调用 successCallback,如果状态为失败,调用 failCallback
            if (this.status === FULFILLED) {
                setTimeout(() => {
                    try {
                        // 获取回调函数的返回值
                        let x = failCallback(this.reason);

                        // 判断 x 的值是普通值还是promise对象
                        // 如果是普通值 直接调用resolve 
                        // 如果是promise对象 查看promsie对象返回的结果 
                        // 再根据promise对象返回的结果 决定调用resolve 还是调用reject

                        // promsie2 是在 new MyPromise 执行完成之后才有的,所以得把这段代码写出异步代码,使用 setTimeout
                        resolvePromise(promsie2, x, resolve, reject)
                    } catch (e) {
                        reject(e);
                    }
                }, 0)
            }
            else if (this.status === REJECTED) {
                setTimeout(() => {
                    try {
                        // 获取回调函数的返回值
                        let x = failCallback(this.reason)

                        // 判断 x 的值是普通值还是promise对象
                        // 如果是普通值 直接调用resolve 
                        // 如果是promise对象 查看promsie对象返回的结果 
                        // 再根据promise对象返回的结果 决定调用resolve 还是调用reject

                        // promsie2 是在 new MyPromise 执行完成之后才有的,所以得把这段代码写出异步代码,使用 setTimeout
                        resolvePromise(promsie2, x, resolve, reject)
                    } catch (e) {
                        reject(e);
                    }
                }, 0)
            }
            else {
                // 当前状态为等待
                // 将成功回调和失败回调存储起来
                this.successCallback.push(() => {
                    setTimeout(() => {
                        try {
                            let x = successCallback(this.value);
                            // 判断 x 的值是普通值还是promise对象
                            // 如果是普通值 直接调用resolve 
                            // 如果是promise对象 查看promsie对象返回的结果 
                            // 再根据promise对象返回的结果 决定调用resolve 还是调用reject
                            resolvePromise(promsie2, x, resolve, reject)
                        } catch (e) {
                            reject(e);
                        }
                    }, 0)
                });
                this.failCallback.push(() => {
                    setTimeout(() => {
                        try {
                            let x = failCallback(this.reason);
                            // 判断 x 的值是普通值还是promise对象
                            // 如果是普通值 直接调用resolve 
                            // 如果是promise对象 查看promsie对象返回的结果 
                            // 再根据promise对象返回的结果 决定调用resolve 还是调用reject
                            resolvePromise(promsie2, x, resolve, reject)
                        } catch (e) {
                            reject(e);
                        }
                    }, 0)
                }); s
            }
        })
        return promise2
    }
}
function resolvePromise(promsie2, x, resolve, reject) {
    // 如果 then 中回调函数返回的 promise 对象和 then 返回的 promise 对象一样,就抛出异常
    if (promsie2 === x) {
        return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
    }
    if (x instanceof MyPromise) {
        // promise 对象
        // x.then(value => resolve(value), reason => reject(reason)); 等价于下面代码
        x.then(resolve, reject);
    } else {
        // 普通值
        resolve(x);
    }
}

七、将 then 方法的参数变成可选参数

在 then 方法中不传递任何参数的时候就等同于 then(value=>value) 这样就可以将状态传递下去

const PENDING = 'pending'; // 等待
const FULFILLED = 'fulfilled'; // 成功
const REJECTED = 'rejected'; // 失败

class MyPromise {

    // 接收执行器,并且立即执行
    constructor(executor) {
        try {
            executor(this.resolve, this.reject)
        } catch (e) {
            // 如果执行器报错,则执行 reject
            this.reject(e);
        }
    }

    // promsie 状态 ,默认值是 pending
    status = PENDING
    // 成功之后的值
    value = undefined
    // 失败后的原因
    reason = undefined
    // 成功回调
    successCallback = [];
    // 失败回调
    failCallback = [];

    resolve = (value) => {
        // 如果状态不是等待 阻止程序向下执行
        if (this.status !== PENDING) return;
        // 将状态更改为 fulfilled
        this.status = FULFILLED
        // 保存成功之后的值
        this.value = value
        // 判断成功回调是否回调,如果存在就依次调用
        while (this.successCallback.length) {
            // 从前往后执行
            this.successCallback.shift()()
        }
    }

    reject = (reason) => {
        // 如果状态不是等待 阻止程序向下执行
        if (this.status !== PENDING) return;
        // 将状态更改为 rejected
        this.status = REJECTED;
        // 保存失败后的原因
        this.reason = reason
        // 判断失败回调是否回调,如果存在就依次调用
        while (this.failCallback.length) {
            // 从前往后执行
            this.failCallback.shift()()
        }
    }

    then(successCallback, failCallback) {
        // 参数可选
        successCallback = successCallback ? successCallback : value => value;
        // 参数可选
        failCallback = failCallback ? failCallback : reason => { throw reason };
        // 创建一个 promise 对象
        let promise2 = new MyPromise((resolve, reject) => {
            // 判断状态,如果状态为成功,调用 successCallback,如果状态为失败,调用 failCallback
            if (this.status === FULFILLED) {
                setTimeout(() => {
                    try {
                        // 获取回调函数的返回值
                        let x = failCallback(this.reason);

                        // 判断 x 的值是普通值还是promise对象
                        // 如果是普通值 直接调用resolve 
                        // 如果是promise对象 查看promsie对象返回的结果 
                        // 再根据promise对象返回的结果 决定调用resolve 还是调用reject

                        // promsie2 是在 new MyPromise 执行完成之后才有的,所以得把这段代码写出异步代码,使用 setTimeout
                        resolvePromise(promsie2, x, resolve, reject)
                    } catch (e) {
                        reject(e);
                    }
                }, 0)
            }
            else if (this.status === REJECTED) {
                setTimeout(() => {
                    try {
                        // 获取回调函数的返回值
                        let x = failCallback(this.reason)

                        // 判断 x 的值是普通值还是promise对象
                        // 如果是普通值 直接调用resolve 
                        // 如果是promise对象 查看promsie对象返回的结果 
                        // 再根据promise对象返回的结果 决定调用resolve 还是调用reject

                        // promsie2 是在 new MyPromise 执行完成之后才有的,所以得把这段代码写出异步代码,使用 setTimeout
                        resolvePromise(promsie2, x, resolve, reject)
                    } catch (e) {
                        reject(e);
                    }
                }, 0)
            }
            else {
                // 当前状态为等待
                // 将成功回调和失败回调存储起来
                this.successCallback.push(() => {
                    setTimeout(() => {
                        try {
                            let x = successCallback(this.value);
                            // 判断 x 的值是普通值还是promise对象
                            // 如果是普通值 直接调用resolve 
                            // 如果是promise对象 查看promsie对象返回的结果 
                            // 再根据promise对象返回的结果 决定调用resolve 还是调用reject
                            resolvePromise(promsie2, x, resolve, reject)
                        } catch (e) {
                            reject(e);
                        }
                    }, 0)
                });
                this.failCallback.push(() => {
                    setTimeout(() => {
                        try {
                            let x = failCallback(this.reason);
                            // 判断 x 的值是普通值还是promise对象
                            // 如果是普通值 直接调用resolve 
                            // 如果是promise对象 查看promsie对象返回的结果 
                            // 再根据promise对象返回的结果 决定调用resolve 还是调用reject
                            resolvePromise(promsie2, x, resolve, reject)
                        } catch (e) {
                            reject(e);
                        }
                    }, 0)
                }); s
            }
        })
        return promise2
    }
}
function resolvePromise(promsie2, x, resolve, reject) {
    // 如果 then 中回调函数返回的 promise 对象和 then 返回的 promise 对象一样,就抛出异常
    if (promsie2 === x) {
        return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
    }
    if (x instanceof MyPromise) {
        // promise 对象
        // x.then(value => resolve(value), reason => reject(reason)); 等价于下面代码
        x.then(resolve, reject);
    } else {
        // 普通值
        resolve(x);
    }
}

八、Promise.all 方法实现

  • Promise.all 是 Promise 的类方法,用于将多个 Promise 实例,包装成一个新的 Promise 实例
  • Promise.all 方法提供了并行执行异步操作的能力,并且在所有异步操作执行完后才执行回调
  • Promise.all 方法是用来解决异步并发问题的,允许我们通过异步代码调用的顺序,得到异步代码运行的结果
  static all(array) {
    let result = []; // 存放结果
    let index = 0;  // 计数器,当 index 等于 array.length 说明所有异步任务执行完成
    return new MyPromise((resolve, reject) => {
      function addData(key, value) {
        result[key] = value;
        index++;
        if (index === array.length) {
          resolve(result);
        }
      }
      for (let i = 0; i < array.length; i++) {
        let current = array[i];
        if (current instanceof MyPromise) {
          // promise 对象
          current.then(value => addData(i, value), reason => reject(reason))
        } else {
          // 普通值,直接返回
          addData(i, array[i]);
        }
      }
    })
  }

九、Promie.reolve 方法的实现

  • Promise.resolve(value)返回一个以 value 值解析后的 Promise 对象
  • Promise.resolve 如果是普通值,返回值就是一个 promise 对象,并且调用了 resolve()
  static resolve(value) {
    if (value instanceof MyPromise) return value;
    return new MyPromise(resolve => resolve(value));
  }

十、finally 方法的实现

不管这个 promise 对象最终的状态是成功还是失败,finally 方法都会被执行一次,在 finally 方法后面可以链式调用 then 方法,获取当前这个 promise 对象最终返回的结果

  finally(callback) {
    // 通过 this.then 来获取当前 promise 的状态
    return this.then(value => {
      return MyPromise.resolve(callback()).then(() => value);
    }, reason => {
      return MyPromise.resolve(callback()).then(() => { throw reason })
    })
  }

十一、catch 方法的实现

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