PromisA+规范

207 阅读1分钟
 function MyPromise(exector) {
        let self = this;
        self.value = undefined;// 存储成功状态下的值
        self.reason = undefined;// 存储失败状态下的原因
        self.status = 'pending';// 存储promise的状态
        self.resCallback = [];// 存储成功的回调函数
        self.rejCallback = [];// 存储失败的回调函数
        function resolve(value) {
            setTimeout(() => {
                if (self.status === 'pending') {
                    self.status = 'resolved'
                    self.value = value;
                    self.resCallback.forEach(item => {
                        item && item(self.value)
                    })
                }
            });
        }
        function reject(reason) {
            setTimeout(() => {
                if (self.status === 'pending') {
                    self.status = 'rejected'
                    self.reason = reason;
                    self.rejCallback.forEach(item => {
                        item && item(self.reason);
                    })
                }
            });
        }
        try {
            exector(resolve, reject)
        } catch (error) {
            reject(error)
        }
    }
    MyPromise.prototype.then = function (res, rej) {
        let self = this;
        return new MyPromise(function (res2, rej2) {
            if (self.status === 'resolved') {
                // 第二个then的回调函数参数是由第一个then的回调函数的执行结果赋予的
                try {
                    let value = res(self.value);
                    res2(value)
                } catch (error) {
                    rej2(error)
                }
            }
            if (self.status === 'rejected') {
                try {
                    let reason = rej(self.reason);
                    // 上一个失败回调 执行没出现错误
                    // 就需要让下一个then的成功回调函数执行
                    res2(reason)
                } catch (error) {
                    rej2(error)
                }
            }
            if (self.status === 'pending') {
                // self.resCallback.push(res);
                // self.rejCallback.push(rej);
                self.resCallback.push(function (value) {
                    try {
                        let val = res(value);
                        res2(val);
                    } catch (error) {
                        rej2(error)
                    }
                })
                self.rejCallback.push(function (reason) {
                    try {
                        let val = rej(reason);
                        res2(val);
                    } catch (error) {
                        rej2(error)
                    }
                })
            }
        })
    }
    MyPromise.all = function (ary) {
        // ary 中都是MyPromise实例
        return new MyPromise(function (res, rej) {
            let done = gen(ary.length, res);
            ary.forEach((item, index) => {
                item.then((data) => {
                    done(index, data)
                }, rej)
            })
        })
    }
    function gen(length, res) {
        let values = [];
        let count = 0;
        return function (index, value) {
            values[index] = value;
            if (++count == length) {
                res(values)
            }
        }
    }
    let myp1 = new MyPromise((res, rej) => {
        setTimeout(() => {
            res(666)
        }, 2000);
    })
    let myp2 = new MyPromise((res, rej) => {
        setTimeout(() => {
            res(999)
        }, 4000);
    })
    MyPromise.all([myp1, myp2]).then((data) => {
        console.log(data)
    }, (err) => {
        console.log(err)
    })