Promise之自定义封装

一、初始化结构搭建

//1.定义 Promise 构造函数
// executor 外界传入的立即执行函数
function Promise(executor) {

}

//2.添加 then 方法
Promise.prototype.then = function (onResolved, onRejected) {

}

二、resolve 与 reject 结构搭建

//1.定义 Promise 构造函数
// executor 外界传入的【执行期函数】
function Promise(executor) {
    //❗️定义 resolve 函数
    function resolve(data) {

    }
    //❗️定义 reject 函数
    function reject(data) {

    }
    //❗️同步调用【执行期函数】
    executor(resolve, reject)
}

//2.添加 then 方法
Promise.prototype.then = function (onResolved, onRejected) {

}

三、resolve 与 reject 代码实现

//1.定义 Promise 构造函数
// executor 外界传入的【执行期函数】
function Promise(executor) {
    //❗️添加属性
    this.PromiseState = 'pending';
    this.PromiseResult = null;

    //❗️保存实例对象的 this 的值
    const self = this;

    //定义 resolve 函数
    function resolve(data) {
        //❗️1. 修改对象的状态
        //this.PromiseState = 'fulfilled'; 🙅错误: 因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseState = 'fulfilled';
        //❗️2. 修改对象结果值
        //this.PromiseResult = data;  🙅错误:因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseResult = data;
    }

    //定义 reject 函数
    function reject(data) {
        //❗️1. 修改对象的状态
        //this.PromiseState = 'rejected'; 🙅错误: 因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseState = 'rejected';
        //❗️2. 修改对象结果值
        //this.PromiseResult = data;  🙅错误:因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseResult = data;
    }

    //同步调用【执行期函数】
    executor(resolve, reject)
}

//2.添加 then 方法
Promise.prototype.then = function (onResolved, onRejected) {

}

四、throw 抛出异常改变状态

📝 改变Promise 对象的状态三种方式   

resolve('Ok')     成功态   
reject('error')    失败态   
throw  'error'    失败态(抛出异常)
//1.定义 Promise 构造函数
// executor 外界传入的【执行期函数】
function Promise(executor) {
    //添加属性
    this.PromiseState = 'pending';
    this.PromiseResult = null;

    //保存实例对象的 this 的值
    const self = this;

    //定义 resolve 函数
    function resolve(data) {
        //1. 修改对象的状态
        //this.PromiseState = 'fulfilled'; 🙅错误: 因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseState = 'fulfilled';
        //2. 修改对象结果值
        //this.PromiseResult = data;  🙅错误:因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseResult = data;
    }

    //定义 reject 函数
    function reject(data) {
        //1. 修改对象的状态
        //this.PromiseState = 'rejected'; 🙅错误: 因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseState = 'rejected';
        //2. 修改对象结果值
        //this.PromiseResult = data;  🙅错误:因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseResult = data;
    }

    //❗️添加处理throw抛出异常逻辑
    try {
        //同步调用【执行期函数】
        executor(resolve, reject)
    } catch (error) {
        //修改 Promise 对象状态为失败
        reject(error)
    }
}

//2.添加 then 方法
Promise.prototype.then = function (onResolved, onRejected) {

}

五、Promise 对象状态只能修改一次

//1.定义 Promise 构造函数
// executor 外界传入的【执行期函数】
function Promise(executor) {
    //添加属性
    this.PromiseState = 'pending';
    this.PromiseResult = null;

    //保存实例对象的 this 的值
    const self = this;

    //定义 resolve 函数
    function resolve(data) {
        //❗️判断状态,保证Promise对象状态只能修改一次
        if (self.PromiseState != 'pending')return
        //1. 修改对象的状态
        //this.PromiseState = 'fulfilled'; 🙅错误: 因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseState = 'fulfilled';
        //2. 修改对象结果值
        //this.PromiseResult = data;  🙅错误:因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseResult = data;
    }

    //定义 reject 函数
    function reject(data) {
        //❗️判断状态,保证Promise对象状态只能修改一次
        if (self.PromiseState != 'pending')return
        //1. 修改对象的状态
        //this.PromiseState = 'rejected'; 🙅错误: 因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseState = 'rejected';
        //2. 修改对象结果值
        //this.PromiseResult = data;  🙅错误:因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseResult = data;
    }

    //添加处理throw抛出异常逻辑
    try {
        //同步调用【执行期函数】
        executor(resolve, reject)
    } catch (error) {
        //修改 Promise 对象状态为失败
        reject(error)
    }
}

//2.添加 then 方法
Promise.prototype.then = function (onResolved, onRejected) {

}

六、then方法执行回调

//1.定义 Promise 构造函数
// executor 外界传入的【执行期函数】
function Promise(executor) {
    //添加属性
    this.PromiseState = 'pending';
    this.PromiseResult = null;

    //保存实例对象的 this 的值
    const self = this;

    //定义 resolve 函数
    function resolve(data) {
        //判断状态,保证Promise对象状态只能修改一次
        if (self.PromiseState != 'pending') return
        //1. 修改对象的状态
        //this.PromiseState = 'fulfilled'; 🙅错误: 因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseState = 'fulfilled';
        //2. 修改对象结果值
        //this.PromiseResult = data;  🙅错误:因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseResult = data;
    }

    //定义 reject 函数
    function reject(data) {
        //判断状态,保证Promise对象状态只能修改一次
        if (self.PromiseState != 'pending') return
        //1. 修改对象的状态
        //this.PromiseState = 'rejected'; 🙅错误: 因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseState = 'rejected';
        //2. 修改对象结果值
        //this.PromiseResult = data;  🙅错误:因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseResult = data;
    }

    //添加处理throw抛出异常逻辑
    try {
        //同步调用【执行期函数】
        executor(resolve, reject)
    } catch (error) {
        //修改 Promise 对象状态为失败
        reject(error)
    }
}

//2.添加 then 方法
Promise.prototype.then = function (onResolved, onRejected) {
    //❗️调用回调函数
    //如果状态为成功
    if (this.PromiseState === 'fulfilled') {
        onResolved(this.PromiseResult)
    }

    //如果状态为失败
    if (this.PromiseState === 'rejected') {
        onRejected(this.PromiseState)
    }
}

⚠️注意:本次添加的逻辑,只能处理同步回调任务!

七、异步任务回调的执行

//1.定义 Promise 构造函数
// executor 外界传入的【执行期函数】
function Promise(executor) {
    //添加属性
    this.PromiseState = 'pending';
    this.PromiseResult = null;
    //❗️声明属性,用户保存{onResolved,onRejected}函数
    this.callback = {}

    //保存实例对象的 this 的值
    const self = this;

    //定义 resolve 函数
    function resolve(data) {
        //判断状态,保证Promise对象状态只能修改一次
        if (self.PromiseState != 'pending') return
        //1. 修改对象的状态
        //this.PromiseState = 'fulfilled'; 🙅错误: 因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseState = 'fulfilled';
        //2. 修改对象结果值
        //this.PromiseResult = data;  🙅错误:因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseResult = data;
        //❗️3.调用成功回调
        if (self.callback.onResolved) {
            self.callback.onResolved(data)
        }
    }

    //定义 reject 函数
    function reject(data) {
        //判断状态,保证Promise对象状态只能修改一次
        if (self.PromiseState != 'pending') return
        //1. 修改对象的状态
        //this.PromiseState = 'rejected'; 🙅错误: 因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseState = 'rejected';
        //2. 修改对象结果值
        //this.PromiseResult = data;  🙅错误:因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseResult = data;
        //❗️3.调用失败回调
        if (self.callback.onRejected) {
            self.callback.onRejected(data)
        }
    }

    //添加处理throw抛出异常逻辑
    try {
        //同步调用【执行期函数】
        executor(resolve, reject)
    } catch (error) {
        //修改 Promise 对象状态为失败
        reject(error)
    }
}

//2.添加 then 方法
Promise.prototype.then = function (onResolved, onRejected) {
    //调用回调函数
    //如果状态为成功
    if (this.PromiseState === 'fulfilled') {
        onResolved(this.PromiseResult)
    }

    //如果状态为失败
    if (this.PromiseState === 'rejected') {
        onRejected(this.PromiseState)
    }

    //❗️判断 pending 状态
    if (this.PromiseState === 'pending') {
        //保存回调函数
        this.callback = {
            onResolved,
            onRejected
        }
    }
}

⚠️注意:本次添加的逻辑,补充了处理异步回调任务!

八、执行多个回调的实现

//1.定义 Promise 构造函数
// executor 外界传入的【执行期函数】
function Promise(executor) {
    //添加属性
    this.PromiseState = 'pending';
    this.PromiseResult = null;
    //❗️声明属性,用户保存{onResolved,onRejected}函数
    // this.callback = {}  🙅问题:如果是单个对象,我们每次then之后保存的回调函数,都会覆盖掉之前的回调函数,这样无法实现then函数链式调用每次都执行的效果
    this.callbacks = {}

    //保存实例对象的 this 的值
    const self = this;

    //定义 resolve 函数
    function resolve(data) {
        //判断状态,保证Promise对象状态只能修改一次
        if (self.PromiseState != 'pending') return
        //1. 修改对象的状态
        //this.PromiseState = 'fulfilled'; 🙅错误: 因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseState = 'fulfilled';
        //2. 修改对象结果值
        //this.PromiseResult = data;  🙅错误:因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseResult = data;
        //❗️3.调用成功回调
        // if (self.callback.onResolved) {
        //     self.callback.onResolved(data)
        // }
        self.callbacks.forEach(item => {
            item.onResolved(data)
        });
    }

    //定义 reject 函数
    function reject(data) {
        //判断状态,保证Promise对象状态只能修改一次
        if (self.PromiseState != 'pending') return
        //1. 修改对象的状态
        //this.PromiseState = 'rejected'; 🙅错误: 因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseState = 'rejected';
        //2. 修改对象结果值
        //this.PromiseResult = data;  🙅错误:因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseResult = data;
        //❗️3.调用失败回调
        // if (self.callback.onRejected) {
        //     self.callback.onRejected(data)
        // }
        self.callbacks.forEach(item => {
            item.onRejected(data)
        });
    }

    //添加处理throw抛出异常逻辑
    try {
        //同步调用【执行期函数】
        executor(resolve, reject)
    } catch (error) {
        //修改 Promise 对象状态为失败
        reject(error)
    }
}

//2.添加 then 方法
Promise.prototype.then = function (onResolved, onRejected) {
    //调用回调函数
    //如果状态为成功
    if (this.PromiseState === 'fulfilled') {
        onResolved(this.PromiseResult)
    }

    //如果状态为失败
    if (this.PromiseState === 'rejected') {
        onRejected(this.PromiseState)
    }

    //❗️判断 pending 状态
    if (this.PromiseState === 'pending') {
        //保存回调函数
        // 🙅问题:如果是单个对象,我们每次then之后保存的回调函数,都会覆盖掉之前的回调函数,这样无法实现then函数链式调用每次都执行的效果
        // this.callback = {
        //     onResolved,
        //     onRejected
        // }
        this.callbacks.push({
            onResolved,
            onRejected
        })
    }
}

九、同步修改状态then方法结果返回

//1.定义 Promise 构造函数
// executor 外界传入的【执行期函数】
function Promise(executor) {
    //添加属性
    this.PromiseState = 'pending';
    this.PromiseResult = null;
    //声明属性,用户保存{onResolved,onRejected}函数
    // this.callback = {}  🙅问题:如果是单个对象,我们每次then之后保存的回调函数,都会覆盖掉之前的回调函数,这样无法实现then函数链式调用每次都执行的效果
    this.callbacks = {}

    //保存实例对象的 this 的值
    const self = this;

    //定义 resolve 函数
    function resolve(data) {
        //判断状态,保证Promise对象状态只能修改一次
        if (self.PromiseState != 'pending') return
        //1. 修改对象的状态
        //this.PromiseState = 'fulfilled'; 🙅错误: 因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseState = 'fulfilled';
        //2. 修改对象结果值
        //this.PromiseResult = data;  🙅错误:因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseResult = data;
        //3.调用成功回调
        // if (self.callback.onResolved) {
        //     self.callback.onResolved(data)
        // }
        self.callbacks.forEach(item => {
            item.onResolved(data)
        });
    }

    //定义 reject 函数
    function reject(data) {
        //判断状态,保证Promise对象状态只能修改一次
        if (self.PromiseState != 'pending') return
        //1. 修改对象的状态
        //this.PromiseState = 'rejected'; 🙅错误: 因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseState = 'rejected';
        //2. 修改对象结果值
        //this.PromiseResult = data;  🙅错误:因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseResult = data;
        //3.调用失败回调
        // if (self.callback.onRejected) {
        //     self.callback.onRejected(data)
        // }
        self.callbacks.forEach(item => {
            item.onRejected(data)
        });
    }

    //添加处理throw抛出异常逻辑
    try {
        //同步调用【执行期函数】
        executor(resolve, reject)
    } catch (error) {
        //修改 Promise 对象状态为失败
        reject(error)
    }
}

//2.添加 then 方法
Promise.prototype.then = function (onResolved, onRejected) {
    return new Promise((resolve, reject) => {
        //调用回调函数
        //❗️如果状态为成功
        if (this.PromiseState === 'fulfilled') {
            try {
                //获取回调函数的执行结果
                let result = onResolved(this.PromiseResult)
                //判断是否为Promise 对象
                if (result instanceof Promise) {
                    result.then(ref => {
                        resolve(ref)
                    }, reason => {
                        reject(reason)
                    })
                } else {
                    //结果的对象状态为成功
                    resolve(result);
                }
            } catch (error) {
                reject(error)
            }
        }

        //如果状态为失败
        if (this.PromiseState === 'rejected') {
            onRejected(this.PromiseState)
        }

        //判断 pending 状态
        if (this.PromiseState === 'pending') {
            //保存回调函数
            // 🙅问题:如果是单个对象,我们每次then之后保存的回调函数,都会覆盖掉之前的回调函数,这样无法实现then函数链式调用每次都执行的效果
            // this.callback = {
            //     onResolved,
            //     onRejected
            // }
            this.callbacks.push({
                onResolved,
                onRejected
            })
        }
    })
}

十、异步修改状态then方法结果返回

//1.定义 Promise 构造函数
// executor 外界传入的【执行期函数】
function Promise(executor) {
    //添加属性
    this.PromiseState = 'pending';
    this.PromiseResult = null;
    //声明属性,用户保存{onResolved,onRejected}函数
    // this.callback = {}  🙅问题:如果是单个对象,我们每次then之后保存的回调函数,都会覆盖掉之前的回调函数,这样无法实现then函数链式调用每次都执行的效果
    this.callbacks = {}

    //保存实例对象的 this 的值
    const self = this;

    //定义 resolve 函数
    function resolve(data) {
        //判断状态,保证Promise对象状态只能修改一次
        if (self.PromiseState != 'pending') return
        //1. 修改对象的状态
        //this.PromiseState = 'fulfilled'; 🙅错误: 因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseState = 'fulfilled';
        //2. 修改对象结果值
        //this.PromiseResult = data;  🙅错误:因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseResult = data;
        //3.调用成功回调
        // if (self.callback.onResolved) {
        //     self.callback.onResolved(data)
        // }
        self.callbacks.forEach(item => {
            item.onResolved(data)
        });
    }

    //定义 reject 函数
    function reject(data) {
        //判断状态,保证Promise对象状态只能修改一次
        if (self.PromiseState != 'pending') return
        //1. 修改对象的状态
        //this.PromiseState = 'rejected'; 🙅错误: 因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseState = 'rejected';
        //2. 修改对象结果值
        //this.PromiseResult = data;  🙅错误:因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseResult = data;
        //3.调用失败回调
        // if (self.callback.onRejected) {
        //     self.callback.onRejected(data)
        // }
        self.callbacks.forEach(item => {
            item.onRejected(data)
        });
    }

    //添加处理throw抛出异常逻辑
    try {
        //同步调用【执行期函数】
        executor(resolve, reject)
    } catch (error) {
        //修改 Promise 对象状态为失败
        reject(error)
    }
}

//2.添加 then 方法
Promise.prototype.then = function (onResolved, onRejected) {
    return new Promise((resolve, reject) => {
        //调用回调函数
        //如果状态为成功
        if (this.PromiseState === 'fulfilled') {
            try {
                //获取回调函数的执行结果
                let result = onResolved(this.PromiseResult)
                //判断是否为Promise 对象
                if (result instanceof Promise) {
                    result.then(ref => {
                        resolve(ref)
                    }, reason => {
                        reject(reason)
                    })
                } else {
                    //结果的对象状态为成功
                    resolve(result);
                }
            } catch (error) {
                reject(error)
            }
        }

        //如果状态为失败
     //⚠️:待补充完善,下面会补充
if (this.PromiseState === 'rejected') { onRejected(this.PromiseState) } //❗️判断 pending 状态 if (this.PromiseState === 'pending') { //保存回调函数 // 🙅问题:如果是单个对象,我们每次then之后保存的回调函数,都会覆盖掉之前的回调函数,这样无法实现then函数链式调用每次都执行的效果 // this.callback = { // onResolved, // onRejected // } this.callbacks.push({ //🙅问题: 当异步修改状态时,由于此时的Promised对象还为pending状态,并不符合需求 // onResolved, // onRejected onResolved: function () { try { // 执行成功回调 let result = onResolved(self.PromiseResult) //判断 if (result instanceof Promise) { result.then((ref) => { resolve(ref) }, (reason) => { reject(reason) }) } else { resolve(result) } } catch (error) { reject(error) } }, onRejected: function () { try { // 执行成功回调 let result = onRejected(self.PromiseResult) //判断 if (result instanceof Promise) { result.then((ref) => { resolve(ref) }, (reason) => { reject(reason) }) } else { resolve(result) } } catch (error) { reject(error) } } }) } }) }

十一、then方法完善和优化

//1.定义 Promise 构造函数
// executor 外界传入的【执行期函数】
function Promise(executor) {
    //添加属性
    this.PromiseState = 'pending';
    this.PromiseResult = null;
    //声明属性,用户保存{onResolved,onRejected}函数
    // this.callback = {}  🙅问题:如果是单个对象,我们每次then之后保存的回调函数,都会覆盖掉之前的回调函数,这样无法实现then函数链式调用每次都执行的效果
    this.callbacks = {}

    //保存实例对象的 this 的值
    const self = this;

    //定义 resolve 函数
    function resolve(data) {
        //判断状态,保证Promise对象状态只能修改一次
        if (self.PromiseState != 'pending') return
        //1. 修改对象的状态
        //this.PromiseState = 'fulfilled'; 🙅错误: 因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseState = 'fulfilled';
        //2. 修改对象结果值
        //this.PromiseResult = data;  🙅错误:因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseResult = data;
        //3.调用成功回调
        // if (self.callback.onResolved) {
        //     self.callback.onResolved(data)
        // }
        self.callbacks.forEach(item => {
            item.onResolved(data)
        });
    }

    //定义 reject 函数
    function reject(data) {
        //判断状态,保证Promise对象状态只能修改一次
        if (self.PromiseState != 'pending') return
        //1. 修改对象的状态
        //this.PromiseState = 'rejected'; 🙅错误: 因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseState = 'rejected';
        //2. 修改对象结果值
        //this.PromiseResult = data;  🙅错误:因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseResult = data;
        //3.调用失败回调
        // if (self.callback.onRejected) {
        //     self.callback.onRejected(data)
        // }
        self.callbacks.forEach(item => {
            item.onRejected(data)
        });
    }

    //添加处理throw抛出异常逻辑
    try {
        //同步调用【执行期函数】
        executor(resolve, reject)
    } catch (error) {
        //修改 Promise 对象状态为失败
        reject(error)
    }
}

//2.❗️添加 then 方法
Promise.prototype.then = function (onResolved, onRejected) {
    const self = this
    return new Promise((resolve, reject) => {
        //1.封装函数 (‘fulfilled’,‘rejected’,‘pending’)代码有太多重复
        function callback(type) {
            try {
                //获取回调函数的执行结果
                let result = type(self.PromiseResult)
                //判断是否为Promise 对象
                if (result instanceof Promise) {
                    result.then(ref => {
                        resolve(ref)
                    }, reason => {
                        reject(reason)
                    })
                } else {
                    //结果的对象状态为成功
                    resolve(result);
                }
            } catch (error) {
                reject(error)
            }
        }

        //调用回调函数
        //如果状态为成功
        if (this.PromiseState === 'fulfilled') {
            callback(onResolved)
        }

        // 如果状态为失败(补充逻辑)
        if (this.PromiseState === 'rejected') {
            callback(onRejected)
        }

        // 判断 pending 状态
        if (this.PromiseState === 'pending') {
            //保存回调函数
            // 🙅问题:如果是单个对象,我们每次then之后保存的回调函数,都会覆盖掉之前的回调函数,这样无法实现then函数链式调用每次都执行的效果
            // this.callback = {
            //     onResolved,
            //     onRejected
            // }
            this.callbacks.push({
                //🙅问题: 当异步修改状态时,由于此时的Promised对象还为pending状态,并不符合需求
                // onResolved,
                // onRejected
                onResolved: function () {
                    callback(onResolved)
                },
                onRejected: function () {
                    callback(onRejected)
                }
            })
        }
    })
}

十二、catch方法-异常穿透与传值

//1.定义 Promise 构造函数
// executor 外界传入的【执行期函数】
function Promise(executor) {
    //添加属性
    this.PromiseState = 'pending';
    this.PromiseResult = null;
    //声明属性,用户保存{onResolved,onRejected}函数
    // this.callback = {}  🙅问题:如果是单个对象,我们每次then之后保存的回调函数,都会覆盖掉之前的回调函数,这样无法实现then函数链式调用每次都执行的效果
    this.callbacks = {}

    //保存实例对象的 this 的值
    const self = this;

    //定义 resolve 函数
    function resolve(data) {
        //判断状态,保证Promise对象状态只能修改一次
        if (self.PromiseState != 'pending') return
        //1. 修改对象的状态
        //this.PromiseState = 'fulfilled'; 🙅错误: 因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseState = 'fulfilled';
        //2. 修改对象结果值
        //this.PromiseResult = data;  🙅错误:因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseResult = data;
        //3.调用成功回调
        // if (self.callback.onResolved) {
        //     self.callback.onResolved(data)
        // }
        self.callbacks.forEach(item => {
            item.onResolved(data)
        });
    }

    //定义 reject 函数
    function reject(data) {
        //判断状态,保证Promise对象状态只能修改一次
        if (self.PromiseState != 'pending') return
        //1. 修改对象的状态
        //this.PromiseState = 'rejected'; 🙅错误: 因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseState = 'rejected';
        //2. 修改对象结果值
        //this.PromiseResult = data;  🙅错误:因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseResult = data;
        //3.调用失败回调
        // if (self.callback.onRejected) {
        //     self.callback.onRejected(data)
        // }
        self.callbacks.forEach(item => {
            item.onRejected(data)
        });
    }

    //添加处理throw抛出异常逻辑
    try {
        //同步调用【执行期函数】
        executor(resolve, reject)
    } catch (error) {
        //修改 Promise 对象状态为失败
        reject(error)
    }
}

//2.添加 then 方法
Promise.prototype.then = function (onResolved, onRejected) {
    const self = this
    
    //❗️判断回调函数参数
    //如果调用者没有传递onResolved,创建一个默认值
    if (typeof onResolved !== 'function') {
        onResolved = ref => {
            return ref
        }
    }
    //如果调用者没有传递onRejected, 创建一个默认值
    //实现catch穿透的原理,
    if (typeof onRejected !== 'function') {
        onRejected = reason => {
            throw reason
        }
    }

    return new Promise((resolve, reject) => {
        //1.封装函数 (‘fulfilled’,‘rejected’,‘pending’)代码有太多重复
        function callback(type) {
            try {
                //获取回调函数的执行结果
                let result = type(self.PromiseResult)
                //判断是否为Promise 对象
                if (result instanceof Promise) {
                    result.then(ref => {
                        resolve(ref)
                    }, reason => {
                        reject(reason)
                    })
                } else {
                    //结果的对象状态为成功
                    resolve(result);
                }
            } catch (error) {
                reject(error)
            }
        }

        //调用回调函数
        //如果状态为成功
        if (this.PromiseState === 'fulfilled') {
            callback(onResolved)
        }

        // 如果状态为失败(补充逻辑)
        if (this.PromiseState === 'rejected') {
            callback(onRejected)
        }

        // 判断 pending 状态
        if (this.PromiseState === 'pending') {
            //保存回调函数
            // 🙅问题:如果是单个对象,我们每次then之后保存的回调函数,都会覆盖掉之前的回调函数,这样无法实现then函数链式调用每次都执行的效果
            // this.callback = {
            //     onResolved,
            //     onRejected
            // }
            this.callbacks.push({
                //🙅问题: 当异步修改状态时,由于此时的Promised对象还为pending状态,并不符合需求
                // onResolved,
                // onRejected
                onResolved: function () {
                    callback(onResolved)
                },
                onRejected: function () {
                    callback(onRejected)
                }
            })
        }
    })
}

//❗️3.添加 catch 方法
Promise.prototype.catch = function (onRejected) {
    return this.then(undefined, onRejected)
}

十三、resolve 方法封装

...//❗️4.添加 resolve 方法
Promise.resolve = function(value) {
    return new Promise((resolve, reject)=>{
        if (value instanceof Promise) {
            value.then((ref)=>{
                resolve(value)
            },(reason)=>{
                reject(reason)
            })
        } else {
            //状态设置为成功
            resolve(value)
        }
    })
}

十四、reject 方法封装

...
//5.添加 reject 方法
Promise.reject = function(reason) {
    return new Promise((resolve,reject)=>{
        reject(reason)
    })
}

十五、all 方法封装

...
//6.添加 all 方法
Promise.all = function (promises) { //promises 为数组
    //返回结果为Promise 对象
    return new Promise((resolve, reject) => {
        //声明变量,用于记录成功数
        let count = 0;
        //声明变量,用于记录Promise 对象成功的结果值,
        let arr = [];
        //遍历
        for (let i = 0; i < promises.length; i++) {
            promises[i].then((res) => {
                //得知对象的状态成功
                //每个promise对象 都成功
                count++
                //判断
                if (count === promises.length) { //成功数与传进来的promises数组长度一致
                    //修改状态
                    resolve(arr)
                }
            }, (resaon) => {
                reject(reason)
            })
        }
    })
}

十六、race 方法封装

...
//7.添加 race 方法
Promise.race = function (promises) {
    return new Promise((resolve, reject) => {
        for (let i; i < promises.length; i++) {
            promises[i].then((res) => {
                //修改返回对象的状态为 【成功】
                resolve(res)
            }, (reason) => {
                //修改返回对象的状态为 【失败】
                reject(r)
            })
        }
    })
}

十七、then方法回调的异步执行

//1.定义 Promise 构造函数
// executor 外界传入的【执行期函数】
function Promise(executor) {
    //添加属性
    this.PromiseState = 'pending';
    this.PromiseResult = null;
    //声明属性,用户保存{onResolved,onRejected}函数
    // this.callback = {}  🙅问题:如果是单个对象,我们每次then之后保存的回调函数,都会覆盖掉之前的回调函数,这样无法实现then函数链式调用每次都执行的效果
    this.callbacks = {}

    //保存实例对象的 this 的值
    const self = this;

    //定义 resolve 函数
    function resolve(data) {
        //判断状态,保证Promise对象状态只能修改一次
        if (self.PromiseState != 'pending') return
        //1. 修改对象的状态
        //this.PromiseState = 'fulfilled'; 🙅错误: 因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseState = 'fulfilled';
        //2. 修改对象结果值
        //this.PromiseResult = data;  🙅错误:因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseResult = data;
        //3.调用成功回调
        // if (self.callback.onResolved) {
        //     self.callback.onResolved(data)
        // }
        //❗️定时器包裹,保证then方法回调的异步执行
        setTimeout(()=>{
            self.callbacks.forEach(item => {
                item.onResolved(data)
            });
        })
    }

    //定义 reject 函数
    function reject(data) {
        //判断状态,保证Promise对象状态只能修改一次
        if (self.PromiseState != 'pending') return
        //1. 修改对象的状态
        //this.PromiseState = 'rejected'; 🙅错误: 因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseState = 'rejected';
        //2. 修改对象结果值
        //this.PromiseResult = data;  🙅错误:因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
        self.PromiseResult = data;
        //3.调用失败回调
        // if (self.callback.onRejected) {
        //     self.callback.onRejected(data)
        // }
        //❗️定时器包裹,保证then方法回调的异步执行
        setTimeout(()=>{
            self.callbacks.forEach(item => {
                item.onRejected(data)
            });
        })
    }

    //添加处理throw抛出异常逻辑
    try {
        //同步调用【执行期函数】
        executor(resolve, reject)
    } catch (error) {
        //修改 Promise 对象状态为失败
        reject(error)
    }
}

//2.添加 then 方法
Promise.prototype.then = function (onResolved, onRejected) {
    const self = this

    //判断回调函数参数
    //如果调用者没有传递onResolved,创建一个默认值
    if (typeof onResolved !== 'function') {
        onResolved = ref => {
            return ref
        }
    }
    //如果调用者没有传递onRejected, 创建一个默认值
    //实现catch穿透的原理,
    if (typeof onRejected !== 'function') {
        onRejected = reason => {
            throw reason
        }
    }

    return new Promise((resolve, reject) => {
        //1.封装函数 (‘fulfilled’,‘rejected’,‘pending’)代码有太多重复
        function callback(type) {
            try {
                //获取回调函数的执行结果
                let result = type(self.PromiseResult)
                //判断是否为Promise 对象
                if (result instanceof Promise) {
                    result.then(ref => {
                        resolve(ref)
                    }, reason => {
                        reject(reason)
                    })
                } else {
                    //结果的对象状态为成功
                    resolve(result);
                }
            } catch (error) {
                reject(error)
            }
        }

        //调用回调函数
        //如果状态为成功
        if (this.PromiseState === 'fulfilled') {
            //❗️定时器包裹,保证then方法回调的异步执行
            setTimeout(()=>{
                callback(onResolved)
            })
        }

        // 如果状态为失败(补充逻辑)
        if (this.PromiseState === 'rejected') {
            //❗️定时器包裹,保证then方法回调的异步执行
            setTimeout(()=>{
                callback(onRejected)
            })
        }

        // 判断 pending 状态
        if (this.PromiseState === 'pending') {
            //保存回调函数
            // 🙅问题:如果是单个对象,我们每次then之后保存的回调函数,都会覆盖掉之前的回调函数,这样无法实现then函数链式调用每次都执行的效果
            // this.callback = {
            //     onResolved,
            //     onRejected
            // }
            this.callbacks.push({
                //🙅问题: 当异步修改状态时,由于此时的Promised对象还为pending状态,并不符合需求
                // onResolved,
                // onRejected
                onResolved: function () {
                    callback(onResolved)
                },
                onRejected: function () {
                    callback(onRejected)
                }
            })
        }
    })
}

十八、class 版本的实现

class Person {
    //构造方法
    constructor(executor) {
        //添加属性
        this.PromiseState = 'pending';
        this.PromiseResult = null;
        //声明属性,用户保存{onResolved,onRejected}函数
        // this.callback = {}  🙅问题:如果是单个对象,我们每次then之后保存的回调函数,都会覆盖掉之前的回调函数,这样无法实现then函数链式调用每次都执行的效果
        this.callbacks = {}

        //保存实例对象的 this 的值
        const self = this;

        //定义 resolve 函数
        function resolve(data) {
            //判断状态,保证Promise对象状态只能修改一次
            if (self.PromiseState != 'pending') return
            //1. 修改对象的状态
            //this.PromiseState = 'fulfilled'; 🙅错误: 因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
            self.PromiseState = 'fulfilled';
            //2. 修改对象结果值
            //this.PromiseResult = data;  🙅错误:因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
            self.PromiseResult = data;
            //3.调用成功回调
            // if (self.callback.onResolved) {
            //     self.callback.onResolved(data)
            // }
            //定时器包裹,保证then方法回调的异步执行
            setTimeout(() => {
                self.callbacks.forEach(item => {
                    item.onResolved(data)
                });
            })
        }

        //定义 reject 函数
        function reject(data) {
            //判断状态,保证Promise对象状态只能修改一次
            if (self.PromiseState != 'pending') return
            //1. 修改对象的状态
            //this.PromiseState = 'rejected'; 🙅错误: 因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
            self.PromiseState = 'rejected';
            //2. 修改对象结果值
            //this.PromiseResult = data;  🙅错误:因为resoluve方法是外界调用,所以这里this指向了调用者,并不是Promise对象
            self.PromiseResult = data;
            //3.调用失败回调
            // if (self.callback.onRejected) {
            //     self.callback.onRejected(data)
            // }
            //定时器包裹,保证then方法回调的异步执行
            setTimeout(() => {
                self.callbacks.forEach(item => {
                    item.onRejected(data)
                });
            })
        }

        //添加处理throw抛出异常逻辑
        try {
            //同步调用【执行期函数】
            executor(resolve, reject)
        } catch (error) {
            //修改 Promise 对象状态为失败
            reject(error)
        }
    }

    // then方法
    then(onResolved, onRejected) {
        const self = this

        //判断回调函数参数
        //如果调用者没有传递onResolved,创建一个默认值
        if (typeof onResolved !== 'function') {
            onResolved = ref => {
                return ref
            }
        }
        //如果调用者没有传递onRejected, 创建一个默认值
        //实现catch穿透的原理,
        if (typeof onRejected !== 'function') {
            onRejected = reason => {
                throw reason
            }
        }

        return new Promise((resolve, reject) => {
            //1.封装函数 (‘fulfilled’,‘rejected’,‘pending’)代码有太多重复
            function callback(type) {
                try {
                    //获取回调函数的执行结果
                    let result = type(self.PromiseResult)
                    //判断是否为Promise 对象
                    if (result instanceof Promise) {
                        result.then(ref => {
                            resolve(ref)
                        }, reason => {
                            reject(reason)
                        })
                    } else {
                        //结果的对象状态为成功
                        resolve(result);
                    }
                } catch (error) {
                    reject(error)
                }
            }

            //调用回调函数
            //如果状态为成功
            if (this.PromiseState === 'fulfilled') {
                //定时器包裹,保证then方法回调的异步执行
                setTimeout(() => {
                    callback(onResolved)
                })
            }

            // 如果状态为失败(补充逻辑)
            if (this.PromiseState === 'rejected') {
                //定时器包裹,保证then方法回调的异步执行
                setTimeout(() => {
                    callback(onRejected)
                })
            }

            // 判断 pending 状态
            if (this.PromiseState === 'pending') {
                //保存回调函数
                // 🙅问题:如果是单个对象,我们每次then之后保存的回调函数,都会覆盖掉之前的回调函数,这样无法实现then函数链式调用每次都执行的效果
                // this.callback = {
                //     onResolved,
                //     onRejected
                // }
                this.callbacks.push({
                    //🙅问题: 当异步修改状态时,由于此时的Promised对象还为pending状态,并不符合需求
                    // onResolved,
                    // onRejected
                    onResolved: function () {
                        callback(onResolved)
                    },
                    onRejected: function () {
                        callback(onRejected)
                    }
                })
            }
        })
    }

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

    // resolve 方法
    static resolve(value) {
        //返回结果为Promise 对象
        return new Promise((resolve, reject) => {
            if (value instanceof Promise) {
                value.then((ref) => {
                    resolve(value)
                }, (reason) => {
                    reject(reason)
                })
            } else {
                //状态设置为成功
                resolve(value)
            }
        })
    }

    // reject 方法
    static reject(reason) {
        return new Promise((resolve, reject) => {
            reject(reason)
        })
    }

    // all 方法
    static all(promises) {
        //返回结果为Promise 对象
        return new Promise((resolve, reject) => {
            //声明变量,用于记录成功数
            let count = 0;
            //声明变量,用于记录Promise 对象成功的结果值,
            let arr = [];
            //遍历
            for (let i = 0; i < promises.length; i++) {
                promises[i].then((res) => {
                    //得知对象的状态成功
                    //每个promise对象 都成功
                    count++
                    //判断
                    if (count === promises.length) { //成功数与传进来的promises数组长度一致
                        //修改状态
                        resolve(arr)
                    }
                }, (resaon) => {
                    reject(reason)
                })
            }
        })
    }

    // race 方法
    static race(promises) {
        return new Promise((resolve, reject) => {
            for (let i; i < promises.length; i++) {
                promises[i].then((res) => {
                    //修改返回对象的状态为 【成功】
                    resolve(res)
                }, (reason) => {
                    //修改返回对象的状态为 【失败】
                    reject(r)
                })
            }
        })
    }
} 

posted on 2024-07-15 10:53  梁飞宇  阅读(20)  评论(0)    收藏  举报