手写Promise

84 阅读16分钟

我们分步来实现promise

step1: 声明_Promise类并绑定this

CODE
class _Promise {
    constructor(cb) {
        this.status = 'pending';
        this.value = null;
        cb(this.resolve.bind(this), this.reject.bind(this));
    }

    resolve(val) {
        this.value = val;
        this.status = 'fulfilled';
    }

    reject(reason) {
        this.value = reason;
        this.status = 'rejected';
    }
}
// 测试
var test = new _Promise((resolve, reject) => {
    resolve('success');
})

// _Promise {status: "fulfilled", value: "success"}

var test = new _Promise((resolve, reject) => {
    resolve('success');
    reject('fail');
})

// _Promise {status: "rejected", value: "fail"}

这里需要注意的一点就是,回调函数需要绑定当前的this,不然因为class内部是严格模式,如果传入的函数执行了resolve或者reject方法时,里面的this为undefined,就会报错。

我们发现,可以先执行resolve,再执行reject,不符合promise状态不可变的特性,所以进行我们的第二步修饰~

step2: 状态保护与执行者异步错误捕获

这个步骤我们做了两件事

  • 当promise的状态为pending时,resolve和reject方法中才能更改状态。
  • 如果cb执行过程中,出现错误,promise状态应该变成reject。所以要给cb增加try catch。
CODE
class _Promise {
    constructor(cb) {
        this.status = 'pending';
        this.value = null;
        try {
            cb(this.resolve.bind(this), this.reject.bind(this));
        } catch(e) {
            this.reject(e);
        }
    }

    resolve(val) {
        if (this.status == 'pending') {
            this.value = val;
            this.status = 'fulfilled';
        }
    }

    reject(reason) {
        if (this.status == 'pending') {
            this.value = reason;
            this.status = 'rejected';
        }
    }
}
// 测试
var test = new _Promise((resolve, reject) => {
    resolve('success');
    reject('fail');
})
// _Promise {status: "fulfilled", value: "success"}

var test = new _Promise((resolve, reject) => {
    console.log(xxxsksks);
})

// Promise {status: "rejected", value: ReferenceError: xxxsksks is not defined
//     at <anonymous>:3:17
//     at new _Promise (<anonymous>:6:…}

step3: Then的基础构建

  • 可以通过then接收promise返回结果,类中声明then方法
  • onFulfilled, onReject方法可以不传
CODE
class _Promise {
    constructor(cb) {
        this.status = 'pending';
        this.value = null;
        try {
            cb(this.resolve.bind(this), this.reject.bind(this));
        } catch(e) {
            this.reject(e);
        }
    }

    resolve(val) {
        if (this.status == 'pending') {
            this.value = val;
            this.status = 'fulfilled';
        }
    }

    reject(reason) {
        if (this.status == 'pending') {
            this.value = reason;
            this.status = 'rejected';
        }
    }

    then(onFulfilled, onReject) {
        if (typeof onFulfilled !== 'function') {
            onFulfilled = () => {}
        }
        
        if (typeof onReject !== 'function') {
            onReject = () => {}
        }
        
        this.status == 'fulfilled' && onFulfilled(this.value);
        this.status == 'rejected' && onReject(this.value);
    }
}
// 测试
new _Promise((resolve, reject) => {
    resolve('success');
}).then(val => {
    console.log(val);
})
// success

new _Promise((resolve, reject) => {
    reject('fail');
}).then(val => {}, reason => {
    console.log(reason);
})
// fail

new _Promise((resolve, reject) => { // 不传reject回调 不会报错
    reject('fail');
}).then(val => {})  

step4: 实现Then的异步操作(微任务)与异常捕获

  • Then方法里的函数也可能报错,报错也要把promise变成rejected状态,也需要加try catch
  • 利用setTimeout模拟微任务的执行顺序
CODE
class _Promise {
    constructor(cb) {
        this.status = 'pending';
        this.value = null;
        try {
            cb(this.resolve.bind(this), this.reject.bind(this));
        } catch(e) {
            this.reject(e);
        }
    }

    resolve(val) {
        if (this.status == 'pending') {
            this.value = val;
            this.status = 'fulfilled';
        }
    }

    reject(reason) {
        if (this.status == 'pending') {
            this.value = reason;
            this.status = 'rejected';
        }
    }

    then(onFulfilled, onReject) {
        if (typeof onFulfilled !== 'function') {
            onFulfilled = () => {}
        }
        
        if (typeof onReject !== 'function') {
            onReject = () => {}
        }
        
        setTimeout(() => { // 模拟微任务顺序
            if (this.status == 'fulfilled') {
                try {
                onFulfilled(this.value);
                } catch(e) {
                    onReject(e);
                }
            } 
            
            if (this.status == 'rejected') {
                try {
                    onReject(this.value);
                } catch(e) {
                    onReject(e);
                }
            }
        })
    }
}
// 测试
new _Promise((resolve, reject) => { 
    resolve('success');
}).then(val => { console.log(sn) }, e => console.log(e))  
// ReferenceError: sn is not defined

new _Promise((resolve, reject) => { 
    reject('fail');
}).then(val => { }, e => console.log(sn))  
// ReferenceError: sn is not defined

new _Promise((resolve, reject) => { 
    resolve('success');
}).then(val => {  console.log(val) }, e => {})  
// 1
// success

step5: _Promise的 pending 状态处理

  • 如果promise不是立即返回结果,也就是.then方法执行而且状态为pending,这时候需要记录回调函数,等待resolve或者reject执行时,执行回调
CODE
class _Promise {
    constructor(cb) {
        this.status = 'pending';
        this.value = null;
        this.thenCbQueue = []; // 记录异步返回结果需要执行的任务队列
        try {
            cb(this.resolve.bind(this), this.reject.bind(this));
        } catch(e) {
            this.reject(e);
        }
    }

    resolve(val) {
        if (this.status == 'pending') {
            this.value = val;
            this.status = 'fulfilled';
            this.thenCbQueue.map(task => { // 执行reslove时 执行成功回调
                task.onFulfilled(this.value);
            });
        }
    }

    reject(reason) {
        if (this.status == 'pending') {
            this.value = reason;
            this.status = 'rejected';
            this.thenCbQueue.map(task => {
                task.onReject(reason); // 执行reslove时 执行失败回调
            });
        }
    }

    then(onFulfilled, onReject) {
        if (typeof onFulfilled !== 'function') {
            onFulfilled = () => {}
        }
        
        if (typeof onReject !== 'function') {
            onReject = () => {}
        }
        
        setTimeout(() => { 
            if (this.status == 'pending') {
                // 记录then方法中的回调函数 注意是一对一对的压哦 
                // 注意所有错误都交给reject方法 后续优化
                this.thenCbQueue.push({ onFulfilled: val => {
                    try {
                        onFulfilled(val);
                    } catch(e) {
                        onReject(e);
                    }
                }, onReject: reason => {
                    try {
                        onReject(reason);
                    } catch(e) {
                        onReject(e);
                    }
                } }); 
            } 

            if (this.status == 'fulfilled') {
                try {
                onFulfilled(this.value);
                } catch(e) {
                    onReject(e);
                }
            } 
            
            if (this.status == 'rejected') {
                try {
                    onReject(this.value);
                } catch(e) {
                    onReject(e);
                }
            }
        })
    }
}
// 测试
new _Promise((resolve, reject) => { 
    setTimeout(() => resolve(1), 1000)
}).then(val => {  console.log(cc) }, e => { console.warn(e) })  

// VM8622:3 ReferenceError: cc is not defined

step6: 异步回调执行顺序跳转

  • 我们希望.then的回调永远是异步的 比如以下代码,我们期望先输出2,再输出1
new _Promise((resolve, reject) => { 
    setTimeout(() => {
        reject(1);
        console.log(2);
    }, 1000)
}).then(val => {  console.log(val) }, e => { console.warn(e) })  

ok, 来改写代码

CODE
class _Promise {
    constructor(cb) {
        this.status = 'pending';
        this.value = null;
        this.thenCbQueue = []; // 记录异步返回结果需要执行的任务队列
        try {
            cb(this.resolve.bind(this), this.reject.bind(this));
        } catch(e) {
            this.reject(e);
        }
    }

    resolve(val) {
        if (this.status == 'pending') {
            this.value = val;
            this.status = 'fulfilled';
            setTimeout(() => { // 增加异步执行逻辑
                this.thenCbQueue.map(task => { 
                    task.onFulfilled(this.value);
                });
            });
        }
    }

    reject(reason) {
        if (this.status == 'pending') {
            this.value = reason;
            this.status = 'rejected';
            setTimeout(() => { // 增加异步执行逻辑
                this.thenCbQueue.map(task => {
                    task.onReject(reason); 
                });
            });
        }
    }

    then(onFulfilled, onReject) {
        if (typeof onFulfilled !== 'function') {
            onFulfilled = () => {}
        }
        
        if (typeof onReject !== 'function') {
            onReject = () => {}
        }
        
        setTimeout(() => { 
            if (this.status == 'pending') {
                // 记录then方法中的回调函数 注意是一对一对的压哦 
                // 注意所有错误都交给reject方法 后续优化
                this.thenCbQueue.push({ onFulfilled: val => {
                    try {
                        onFulfilled(val);
                    } catch(e) {
                        onReject(e);
                    }
                }, onReject: reason => {
                    try {
                        onReject(reason);
                    } catch(e) {
                        onReject(e);
                    }
                } }); 
            } 

            if (this.status == 'fulfilled') {
                try {
                onFulfilled(this.value);
                } catch(e) {
                    onReject(e);
                }
            } 
            
            if (this.status == 'rejected') {
                try {
                    onReject(this.value);
                } catch(e) {
                    onReject(e);
                }
            }
        })
    }
}
// 测试
new _Promise((resolve, reject) => { 
    setTimeout(() => {
        reject(1);
        console.log(2);
    }, 1000)
}).then(val => {  console.log(val) }, e => { console.warn(e) })  
// 2
// 1

step7: .then().then()链式操作

  • 因为每个.then都返回一个promise,我们可以用递归的方式,让.then方法返回一个新的_promsie, 新的_Promise 执行resolve或者reject方法传递上个then 的返回值
  • 注意 then 返回值的promise状态默认是成功的
new _Promise((resolve, reject) => {
   resolve(1)
}).then(val => {
    console.log(val, '111')
    return 'ys'
}).then(val => {
    console.log(val, '222')
})
// Uncaught TypeError: Cannot read property 'then' of undefined
CODE
class _Promise {
    constructor(cb) {
        this.status = 'pending';
        this.value = null;
        this.thenCbQueue = []; // 记录异步返回结果需要执行的任务队列
        try {
            cb(this.resolve.bind(this), this.reject.bind(this));
        } catch(e) {
            this.reject(e);
        }
    }

    resolve(val) {
        if (this.status == 'pending') {
            this.value = val;
            this.status = 'fulfilled';
            setTimeout(() => { // 增加异步执行逻辑
                this.thenCbQueue.map(task => { 
                    task.onFulfilled(this.value);
                });
            });
        }
    }

    reject(reason) {
        if (this.status == 'pending') {
            this.value = reason;
            this.status = 'rejected';
            setTimeout(() => { // 增加异步执行逻辑
                this.thenCbQueue.map(task => {
                    task.onReject(reason); 
                });
            });
        }
    }

    then(onFulfilled, onReject) {
        if (typeof onFulfilled !== 'function') {
            onFulfilled = () => {}
        }
        
        if (typeof onReject !== 'function') {
            onReject = () => {}
        }
        
        // 这里包了一层 _Promise
        return new _Promise((resolve, reject) => {
            setTimeout(() => { 
                if (this.status == 'pending') {
                    this.thenCbQueue.push({ onFulfilled: val => {
                        try {
                            // mark
                            let res = onFulfilled(val);
                            
                            resolve(res);
                        } catch(e) {
                            onReject(e);
                        }
                    }, onReject: reason => {
                        try {
                            // mark 
                            let res = onReject(reason);
                             
                            resolve(res);
                        } catch(e) {
                            onReject(e);
                        }
                    } }); 
                } 
    
                if (this.status == 'fulfilled') {
                    try {
                        // 传递上一个then的返回值 不管后面有没有接收
                        let res = onFulfilled(this.value); 
                        
                        resolve(res);
                    } catch(e) {
                        onReject(e);
                    }
                } 
                
                if (this.status == 'rejected') {
                    try {
                        // 传递上一个then的返回值 不管后面有没有接收
                         let res = onReject(this.value);
                         
                         // 注意 then返回值的promise状态默认是成功的
                         resolve(res); 
                    } catch(e) {
                        onReject(e);
                    }
                }
            })
        })
    }
}
new _Promise((resolve, reject) => {
   resolve(1)
}).then(val => {
    console.log(val, '000')
    return 'success'
}, e => {
    return 'fail'
}).then(val => {
    console.log(val, '111')
}, e => {
    console.log('链式调用then失败?');
})

// 1  "000"
// VM15140:9 success 111

new _Promise((resolve, reject) => {
   reject(1)
}).then(val => {
    console.log(val, '000')
    return 'success'
}, e => {
    console.log(val, '111');
    return 'fail'
}).then(val => {
    console.log(val, '222')
}, e => {
    console.log('链式调用then失败?');
})

// 1  "111"
// VM15140:9 fail 222


new _Promise((resolve, reject) => {
  setTimeout(() => reject(1), 100)
}).then(val => {
    console.log(val, '000')
    return 'success'
}, e => {
    console.log(e, '111');
    return 'fail'
}).then(val => {
    console.log(val, '222')
}, e => {
    console.log('链式调用then失败?');
})

// 1  "111"
// VM15140:9 fail 222

step8: then()方法错误传递

  • .then方法内部错误,需要下一个.then的onReject来捕捉, 修改返回的_Promise的错误处理即可
CODE
class _Promise {
    constructor(cb) {
        this.status = 'pending';
        this.value = null;
        this.thenCbQueue = []; // 记录异步返回结果需要执行的任务队列
        try {
            cb(this.resolve.bind(this), this.reject.bind(this));
        } catch(e) {
            this.reject(e);
        }
    }

    resolve(val) {
        if (this.status == 'pending') {
            this.value = val;
            this.status = 'fulfilled';
            setTimeout(() => { // 增加异步执行逻辑
                this.thenCbQueue.map(task => { 
                    task.onFulfilled(this.value);
                });
            });
        }
    }

    reject(reason) {
        if (this.status == 'pending') {
            this.value = reason;
            this.status = 'rejected';
            setTimeout(() => { // 增加异步执行逻辑
                this.thenCbQueue.map(task => {
                    task.onReject(reason); 
                });
            });
        }
    }

    then(onFulfilled, onReject) {
        if (typeof onFulfilled !== 'function') {
            onFulfilled = () => {}
        }
        
        if (typeof onReject !== 'function') {
            onReject = () => {}
        }
        
        // 这里包了一层 _Promise
        return new _Promise((resolve, reject) => {
            setTimeout(() => { 
                if (this.status == 'pending') {
                    this.thenCbQueue.push({ onFulfilled: val => {
                        try {
                            // mark
                            let res = onFulfilled(val);
                            
                            resolve(res);
                        } catch(e) {
                            reject(e); // onReject -> reject
                        }
                    }, onReject: reason => {
                        try {
                            // mark 
                            let res = onReject(reason);
                             
                            resolve(res);
                        } catch(e) {
                            reject(e); // onReject -> reject
                        }
                    } }); 
                } 
    
                if (this.status == 'fulfilled') {
                    try {
                        // 传递上一个then的返回值 不管后面有没有接收
                        let res = onFulfilled(this.value); 
                        
                        resolve(res);
                    } catch(e) {
                        reject(e); // onReject -> reject
                    }
                } 
                
                if (this.status == 'rejected') {
                    try {
                        // 传递上一个then的返回值 不管后面有没有接收
                         let res = onReject(this.value);
                         
                         // 注意 then返回值的promise状态默认是成功的
                         resolve(res); 
                    } catch(e) {
                        reject(e); // onReject -> reject 
                    }
                }
            })
        })
    }
}
// 测试
new _Promise((resolve, reject) => {
  setTimeout(() => resolve(1), 100)
}).then(val => {
    console.log(aaa, '000')
    return 'success'
}, e => {
    console.log(e, '111');
    return 'fail'
}).then(val => {
    console.log(val, '222')
}, e => {
    console.log('错了错了', e);
})

// 错了错了 ReferenceError: aaa is not defined

step9: 实现then()的穿透传递【reject穿透有问题呀】

  • 如果then方法内部没有传递参数,把变量继续往下传递 return this.value
// 原生promise具有穿透的能力
new Promise((resolve, reject) => {
  reject(1)
}).then().then(val => {
    console.log('resolve', val)
}, e => {
    console.log('reject', e);
})

// reject 1
CODE
class _Promise {
    constructor(cb) {
        this.status = 'pending';
        this.value = null;
        this.thenCbQueue = []; // 记录异步返回结果需要执行的任务队列
        try {
            cb(this.resolve.bind(this), this.reject.bind(this));
        } catch(e) {
            this.reject(e);
        }
    }

    resolve(val) {
        if (this.status == 'pending') {
            this.value = val;
            this.status = 'fulfilled';
            setTimeout(() => { // 增加异步执行逻辑
                this.thenCbQueue.map(task => { 
                    task.onFulfilled(this.value);
                });
            });
        }
    }

    reject(reason) {
        if (this.status == 'pending') {
            this.value = reason;
            this.status = 'rejected';
            setTimeout(() => { // 增加异步执行逻辑
                this.thenCbQueue.map(task => {
                    task.onReject(reason); 
                });
            });
        }
    }

    then(onFulfilled, onReject) {
        if (typeof onFulfilled !== 'function') {
            onFulfilled = () => this.value // 往下传递 被下面res接收
        }
        
        if (typeof onReject !== 'function') {
            onReject = () => this.value // 往下传递 被下面res接收
        }
        
        // 这里包了一层 _Promise
        return new _Promise((resolve, reject) => {
            setTimeout(() => { 
                if (this.status == 'pending') {
                    this.thenCbQueue.push({ onFulfilled: val => {
                        try {
                            // mark
                            let res = onFulfilled(val);
                            
                            resolve(res);
                        } catch(e) {
                            reject(e); // onReject -> reject
                        }
                    }, onReject: reason => {
                        try {
                            // mark 
                            let res = onReject(reason);
                             
                            resolve(res);
                        } catch(e) {
                            reject(e); // onReject -> reject
                        }
                    } }); 
                } 
    
                if (this.status == 'fulfilled') {
                    try {
                        // 传递上一个then的返回值 不管后面有没有接收
                        let res = onFulfilled(this.value); 
                        
                        resolve(res);
                    } catch(e) {
                        reject(e); // onReject -> reject
                    }
                } 
                
                if (this.status == 'rejected') {
                    try {
                        // 传递上一个then的返回值 不管后面有没有接收
                         let res = onReject(this.value);
                         
                         // 注意 then返回值的promise状态默认是成功的
                         resolve(res); 
                    } catch(e) {
                        reject(e); // onReject -> reject 
                    }
                }
            })
        })
    }
}
// 测试
new _Promise((resolve, reject) => {
  reject(1)
}).then().then(val => {
    console.log('resolve', val)
}, e => {
    console.log('reject', e);
})

// resolve 1 我们也实现了这种穿透 但是reject 变成了 resolve ??

step7: then返回promise的处理

  • 如果then返回了一个new _Promise 需要找到对它进行取值返回操作
// 原生promise具有穿透的能力
new Promise((resolve, reject) => {
  resolve(1)
}).then(val => {
    return new Promise(resolve => resolve(val))
}).then(val => {
    console.log('resolve', val);
})

// resolve  1
CODE
class _Promise {
    constructor(cb) {
        this.status = 'pending';
        this.value = null;
        this.thenCbQueue = []; // 记录异步返回结果需要执行的任务队列
        try {
            cb(this.resolve.bind(this), this.reject.bind(this));
        } catch(e) {
            this.reject(e);
        }
    }

    resolve(val) {
        if (this.status == 'pending') {
            this.value = val;
            this.status = 'fulfilled';
            setTimeout(() => { // 增加异步执行逻辑
                this.thenCbQueue.map(task => { 
                    task.onFulfilled(this.value);
                });
            });
        }
    }

    reject(reason) {
        if (this.status == 'pending') {
            this.value = reason;
            this.status = 'rejected';
            setTimeout(() => { // 增加异步执行逻辑
                this.thenCbQueue.map(task => {
                    task.onReject(reason); 
                });
            });
        }
    }

    then(onFulfilled, onReject) {
        if (typeof onFulfilled !== 'function') {
            onFulfilled = () => this.value // 往下传递 被下面res接收
        }
        
        if (typeof onReject !== 'function') {
            onReject = () => this.value // 往下传递 被下面res接收
        }
        
        // 这里包了一层 _Promise
        return new _Promise((resolve, reject) => {
            setTimeout(() => { 
                if (this.status == 'pending') {
                    this.thenCbQueue.push({ onFulfilled: val => {
                        try {
                            // mark
                            let res = onFulfilled(val);
                            
                            if (res instanceof _Promise) {
                                // res 是 _Promise的实例
                                res.then(val => resolve(val), reason => reject(reason))
                            } else {
                                resolve(res);   
                            }
                        } catch(e) {
                            reject(e); // onReject -> reject
                        }
                    }, onReject: reason => {
                        try {
                            // mark 
                            let res = onReject(reason);
                             
                            if (res instanceof _Promise) {
                                // res 是 _Promise的实例
                                res.then(val => resolve(val), reason => reject(reason))
                            } else {
                                resolve(res);   
                            }
                        } catch(e) {
                            reject(e); // onReject -> reject
                        }
                    } }); 
                } 
    
                if (this.status == 'fulfilled') {
                    try {
                        // 传递上一个then的返回值 不管后面有没有接收
                        let res = onFulfilled(this.value); 
                        
                        if (res instanceof _Promise) {
                            // res 是 _Promise的实例
                            res.then(val => resolve(val), reason => reject(reason))
                        } else {
                            resolve(res);   
                        }
                    } catch(e) {
                        reject(e); // onReject -> reject
                    }
                } 
                
                if (this.status == 'rejected') {
                    try {
                        // 传递上一个then的返回值 不管后面有没有接收
                         let res = onReject(this.value);
                         
                        // 注意 then返回值的promise状态默认是成功的
                        if (res instanceof _Promise) {
                            // res 是 _Promise的实例
                            res.then(val => resolve(val), reason => reject(reason))
                        } else {
                            resolve(res);   
                        }
                    } catch(e) {
                        reject(e); // onReject -> reject 
                    }
                }
            })
        })
    }
}
// 测试
new _Promise((resolve, reject) => {
  reject(1)
}).then(val => {
   return new _Promise((resolve, reject) => reject(111));
}).then(val => {
    console.log('resolve', val);
}, val => {
    console.log('reject', val);
})

// resolve 1

new _Promise((resolve, reject) => {
  reject(1)
}).then(val => {}, reason => {
    return new _Promise((resolve, reject) => reject(111))
}).then(val => {
    console.log('resolve', val);
}, val => {
    console.log('reject', val);
})

// reject 111

new _Promise((resolve, reject) => {
  setTimeout(() => reject(1), 100)
}).then(val => {}, reason => {
    return new _Promise((resolve, reject) => reject(111))
}).then(val => {
    console.log('resolve', val);
}, val => {
    console.log('reject', val);
})
//  reject 111

step10: 优化重复代码

CODE
class _Promise {
    constructor(cb) {
        this.status = 'pending';
        this.value = null;
        this.thenCbQueue = []; // 记录异步返回结果需要执行的任务队列
        try {
            cb(this.resolve.bind(this), this.reject.bind(this));
        } catch(e) {
            this.reject(e);
        }
    }

    resolve(val) {
        if (this.status == 'pending') {
            this.value = val;
            this.status = 'fulfilled';
            setTimeout(() => { // 增加异步执行逻辑
                this.thenCbQueue.map(task => { 
                    task.onFulfilled(this.value);
                });
            });
        }
    }

    reject(reason) {
        if (this.status == 'pending') {
            this.value = reason;
            this.status = 'rejected';
            setTimeout(() => { // 增加异步执行逻辑
                this.thenCbQueue.map(task => {
                    task.onReject(reason); 
                });
            });
        }
    }

    then(onFulfilled, onReject) {
        if (typeof onFulfilled !== 'function') {
            onFulfilled = () => this.value // 往下传递 被下面res接收
        }
        
        if (typeof onReject !== 'function') {
            onReject = () => this.value // 往下传递 被下面res接收
        }
        
        // 这里包了一层 _Promise
        return new _Promise((resolve, reject) => {
            setTimeout(() => { 
                if (this.status == 'pending') {
                    this.thenCbQueue.push({ onFulfilled: val => {
                        this.parse(onFulfilled(val), resolve, reject);
                    }, onReject: reason => {
                        this.parse(onReject(reason), resolve, reject);
                    } }); 
                } 
    
                if (this.status == 'fulfilled') {
                   this.parse(onFulfilled(this.value), resolve, reject);
                } 
                
                if (this.status == 'rejected') {
                   this.parse(onReject(this.value), resolve, reject);
                }
            })
        })
    }
    
    
    parse(res, resolve, reject) {
        try {
            // 注意 then返回值的promise状态默认是成功的
            if (res instanceof _Promise) {
                // res 是 _Promise的实例
                res.then(val => resolve(val), reason => reject(reason))
            } else {
                resolve(res);   
            }
        } catch(e) {
            reject(e); // onReject -> reject 
        }
    }
}

step11: then返回类型约束(不能返回实例自身哦)

let p = new Promise((resolve, reject) => {
    resolve('解决');
}).then(val => p);
// TypeError: Chaining cycle detected for promise #<Promise>
CODE
class _Promise {
    constructor(cb) {
        this.status = 'pending';
        this.value = null;
        this.thenCbQueue = []; // 记录异步返回结果需要执行的任务队列
        try {
            cb(this.resolve.bind(this), this.reject.bind(this));
        } catch(e) {
            this.reject(e);
        }
    }

    resolve(val) {
        if (this.status == 'pending') {
            this.value = val;
            this.status = 'fulfilled';
            setTimeout(() => { // 增加异步执行逻辑
                this.thenCbQueue.map(task => { 
                    task.onFulfilled(this.value);
                });
            });
        }
    }

    reject(reason) {
        if (this.status == 'pending') {
            this.value = reason;
            this.status = 'rejected';
            setTimeout(() => { // 增加异步执行逻辑
                this.thenCbQueue.map(task => {
                    task.onReject(reason); 
                });
            });
        }
    }

    then(onFulfilled, onReject) {
        if (typeof onFulfilled !== 'function') {
            onFulfilled = () => this.value // 往下传递 被下面res接收
        }
        
        if (typeof onReject !== 'function') {
            onReject = () => this.value // 往下传递 被下面res接收
        }
        
        // 这里判断 实例调用.then不能返回自身实例
        let promiseInstance = new _Promise((resolve, reject) => {
            setTimeout(() => { 
                if (this.status == 'pending') {
                    this.thenCbQueue.push({ onFulfilled: val => {
                        // 因为setTimeout是异步的 所以可以读到实例..
                        this.parse(promiseInstance, onFulfilled(val), resolve, reject);
                    }, onReject: reason => {
                        this.parse(promiseInstance, onReject(reason), resolve, reject);
                    } }); 
                } 
    
                if (this.status == 'fulfilled') {
                   this.parse(promiseInstance, onFulfilled(this.value), resolve, reject);
                } 
                
                if (this.status == 'rejected') {
                   this.parse(promiseInstance, onReject(this.value), resolve, reject);
                }
            })
        })
        
        return promiseInstance;
    }
    
    
    parse(instance, res, resolve, reject) {
        // 如果实例和.then方法返回的实例一样 报错
        if (instance == res) {
            throw new TypeError('Chaining cycle detected');    
        }
        try {
            // 注意 then返回值的promise状态默认是成功的
            if (res instanceof _Promise) {
                // res 是 _Promise的实例
                res.then(val => resolve(val), reason => reject(reason))
            } else {
                resolve(res);   
            }
        } catch(e) {
            reject(e); // onReject -> reject 
        }
    }
}

// 测试
let p = new _Promise((resolve, reject) => {
    resolve('解决');
}).then(val => p);

// Uncaught TypeError: Chaining cycle detected

step12: resolve,reject静态方法实现(_Promise.xxx)

// 普通值
Promise.resolve(1).then(val => console.log(val)) // 1
// promise 【我们发现后面的成功或者失败状态是依赖返回的promise的状态】
Promise.resolve(new Promise((resolve, reject) => {
    resolve('成功');
})).then(val => console.log('resolve: ' + val), reason => console.log('reject: ' + reason));
// resolve: 成功

Promise.resolve(new Promise((resolve, reject) => {
    reject('失败');
})).then(val => console.log('resolve: ' + val), reason => console.log('reject: ' + reason));
// reject: 失败
CODE
class _Promise {
    constructor(cb) {
        this.status = 'pending';
        this.value = null;
        this.thenCbQueue = []; // 记录异步返回结果需要执行的任务队列
        try {
            cb(this.resolve.bind(this), this.reject.bind(this));
        } catch(e) {
            this.reject(e);
        }
    }

    resolve(val) {
        if (this.status == 'pending') {
            this.value = val;
            this.status = 'fulfilled';
            setTimeout(() => { // 增加异步执行逻辑
                this.thenCbQueue.map(task => { 
                    task.onFulfilled(this.value);
                });
            });
        }
    }

    reject(reason) {
        if (this.status == 'pending') {
            this.value = reason;
            this.status = 'rejected';
            setTimeout(() => { // 增加异步执行逻辑
                this.thenCbQueue.map(task => {
                    task.onReject(reason); 
                });
            });
        }
    }

    then(onFulfilled, onReject) {
        if (typeof onFulfilled !== 'function') {
            onFulfilled = () => this.value // 往下传递 被下面res接收
        }
        
        if (typeof onReject !== 'function') {
            onReject = () => this.value // 往下传递 被下面res接收
        }
        
        // 这里判断 实例调用.then不能返回自身实例
        let promiseInstance = new _Promise((resolve, reject) => {
            setTimeout(() => { 
                if (this.status == 'pending') {
                    this.thenCbQueue.push({ onFulfilled: val => {
                        // 因为setTimeout是异步的 所以可以读到实例..
                        this.parse(promiseInstance, onFulfilled(val), resolve, reject);
                    }, onReject: reason => {
                        this.parse(promiseInstance, onReject(reason), resolve, reject);
                    } }); 
                } 
    
                if (this.status == 'fulfilled') {
                   this.parse(promiseInstance, onFulfilled(this.value), resolve, reject);
                } 
                
                if (this.status == 'rejected') {
                   this.parse(promiseInstance, onReject(this.value), resolve, reject);
                }
            })
        })
        
        return promiseInstance;
    }
    
    
    parse(instance, res, resolve, reject) {
        // 如果实例和.then方法返回的实例一样 报错
        if (instance == res) {
            throw new TypeError('Chaining cycle detected');    
        }
        try {
            // 注意 then返回值的promise状态默认是成功的
            if (res instanceof _Promise) {
                // res 是 _Promise的实例
                res.then(val => resolve(val), reason => reject(reason))
            } else {
                resolve(res);   
            }
        } catch(e) {
            reject(e); // onReject -> reject 
        }
    }
    
    // 静态方法resolve
    static resolve(value) {
        return new _Promise((resolve, reject) => {
            if (value instanceof _Promise) {
                // value 是 _Promise的实例 返回结果成功或者失败依赖value的状态
                value.then(val => resolve(val), reason => reject(reason))
            } else {
                resolve(value);   
            }
        });
    }
    
    // 静态方法reject实现较为简单
    static reject(value) {
        return new _Promise((resolve, reject) => {
            reject(value);   
        });
    }
}

// 测试

// 普通值
_Promise.resolve(1).then(val => console.log(val)) // 1

// promsie
_Promise.resolve(new _Promise((resolve, reject) => {
    resolve('成功');
})).then(val => console.log('resolve: ' + val), reason => console.log('reject: ' + reason));
// 成功

_Promise.resolve(new _Promise((resolve, reject) => {
    reject('失败');
})).then(val => console.log('resolve: ' + val), reason => console.log('reject: ' + reason));
// 失败

step13: _Promise.all方法实现

Promise有以下特性:

  • 接收一个iterable作为参数
  • 全部成功,按传入顺序返回结果集
  • 一个失败,返回失败项
  • 参数列表内元素如果非promise,原样返回
// 全部成功 返回成功结果的集合
let u1 = new Promise(resolve => {
    resolve('ys');
});

let u2 = new Promise(resolve => {
    resolve('笑嘻嘻');
});

Promise.all([u1, u2]).then(val => {
    console.log(val);
});
// ["ys", "笑嘻嘻"]


// 如果有一个失败 则返回失败项 状态为rejected
let u1 = new Promise(resolve => {
    resolve('ys');
});

let u2 = new Promise((result, reject) => {
    reject('哭唧唧');
});

Promise.all([u1, u2]).then(null, reason => {
    console.log(reason);
});
// 哭唧唧
CODE
class _Promise {
    constructor(cb) {
        this.status = 'pending';
        this.value = null;
        this.thenCbQueue = []; // 记录异步返回结果需要执行的任务队列
        try {
            cb(this.resolve.bind(this), this.reject.bind(this));
        } catch(e) {
            this.reject(e);
        }
    }

    resolve(val) {
        if (this.status == 'pending') {
            this.value = val;
            this.status = 'fulfilled';
            setTimeout(() => { // 增加异步执行逻辑
                this.thenCbQueue.map(task => { 
                    task.onFulfilled(this.value);
                });
            });
        }
    }

    reject(reason) {
        if (this.status == 'pending') {
            this.value = reason;
            this.status = 'rejected';
            setTimeout(() => { // 增加异步执行逻辑
                this.thenCbQueue.map(task => {
                    task.onReject(reason); 
                });
            });
        }
    }

    then(onFulfilled, onReject) {
        if (typeof onFulfilled !== 'function') {
            onFulfilled = () => this.value // 往下传递 被下面res接收
        }
        
        if (typeof onReject !== 'function') {
            onReject = () => this.value // 往下传递 被下面res接收
        }
        
        // 这里判断 实例调用.then不能返回自身实例
        let promiseInstance = new _Promise((resolve, reject) => {
            setTimeout(() => { 
                if (this.status == 'pending') {
                    this.thenCbQueue.push({ onFulfilled: val => {
                        // 因为setTimeout是异步的 所以可以读到实例..
                        this.parse(promiseInstance, onFulfilled(val), resolve, reject);
                    }, onReject: reason => {
                        this.parse(promiseInstance, onReject(reason), resolve, reject);
                    } }); 
                } 
    
                if (this.status == 'fulfilled') {
                   this.parse(promiseInstance, onFulfilled(this.value), resolve, reject);
                } 
                
                if (this.status == 'rejected') {
                   this.parse(promiseInstance, onReject(this.value), resolve, reject);
                }
            })
        })
        
        return promiseInstance;
    }
    
    
    parse(instance, res, resolve, reject) {
        // 如果实例和.then方法返回的实例一样 报错
        if (instance == res) {
            throw new TypeError('Chaining cycle detected');    
        }
        try {
            // 注意 then返回值的promise状态默认是成功的
            if (res instanceof _Promise) {
                // res 是 _Promise的实例
                res.then(val => resolve(val), reason => reject(reason))
            } else {
                resolve(res);   
            }
        } catch(e) {
            reject(e); // onReject -> reject
        }
    }
    
    // 静态方法resolve
    static resolve(value) {
        return new _Promise((resolve, reject) => {
            if (value instanceof _Promise) {
                // value 是 _Promise的实例 返回结果成功或者失败依赖value的状态
                value.then(val => resolve(val), reason => reject(reason))
            } else {
                resolve(value);   
            }
        });
    }
    
    // 静态方法reject实现较为简单
    static reject(value) {
        return new _Promise((resolve, reject) => {
            reject(value);   
        });
    }
    
    // 传进来的是一个promise实例列表
    static all(promises) {
        // if (!Array.isArray(promises)) {
        //   throw new Error("promises must be an iterator")
        // }
        // 注意 参数必须为迭代器对象
        // 迭代器对象能调用...方法转为数组
        // Array.form能将一个没有部署迭代器的类数组转成数组 所以不适合判断
        if (typeof promises[Symbol.iterator] !== 'function') {
            console.log(new TypeError('object is not iterable'));
        }


        return new _Promise((resolve, reject) => {
 

            let resolvedCount = 0;
            let successPromiseSet = []; // 成功的结果数组
            
            // 迭代器对象能调用...方法转为数组 再调用forEach
            Array.from(promises).forEach((promise, idx) => {
                // 可能输入的不是一个promise 如果不是promise对象原样返回
                // 为了兼容都能调用then方法 用resolve包一层
                _Promise.resolve(promise).then(val => {
                    successPromiseSet[idx] = val;
                    resolvedCount++;
                    
                    // 如果结果的数量 = 传递的promise数量 则返回结果集
                    resolvedCount == promises.length && resolve(successPromiseSet);
                }, reason => {
                    reject(reason);
                });
            });
        })
    }
}

// 测试
var u1 = new _Promise(resolve => {
    setTimeout(() => {
        resolve('ys');
    }, 200);
});


var u2 = new _Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('笑嘻嘻');
    }, 15000)
});

var u3 = new _Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('lalal');
    }, 500)
});

var u4 = 4;
// all result is : ["ys","笑嘻嘻","lalal",4]


var u1 = new _Promise(resolve => {
    resolve('ys');
});

let u2 = new _Promise((resolve, reject) => {
    reject('笑嘻嘻');
});

_Promise.all([u1, u2]).then(null, reason => {
    console.log('reject: ' + reason);
});
// reject: 笑嘻嘻

step14: _Promise.race静态方法实现

谁快用谁,这个实现起来相当好写, 有值回来 返回即可

var u1 = new Promise(resolve => {
    setTimeout(() => {
        resolve('ys');
    }, 2000);
});


var u2 = new Promise(resolve => {
    setTimeout(() => {
        resolve('笑嘻嘻');
    }, 1000)
});

Promise.race([u1, u2]).then(val => console.log('race winner is : ' + val));
// race winner is : 笑嘻嘻

// 失败状态也可以哦
var u1 = new Promise(resolve => {
    setTimeout(() => {
        resolve('ys');
    }, 2000);
});


var u2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject('笑嘻嘻');
    }, 1000)
});

Promise.race([u1, u2]).then(val => console.log('race winner is : ' + val), reason => console.warn('reject: race winner is : ' + reason));
// VM117142:14 reject: race winner is : 笑嘻嘻
CODE
class _Promise {
    constructor(cb) {
        this.status = 'pending';
        this.value = null;
        this.thenCbQueue = []; // 记录异步返回结果需要执行的任务队列
        try {
            cb(this.resolve.bind(this), this.reject.bind(this));
        } catch(e) {
            this.reject(e);
        }
    }

    resolve(val) {
        if (this.status == 'pending') {
            this.value = val;
            this.status = 'fulfilled';
            setTimeout(() => { // 增加异步执行逻辑
                this.thenCbQueue.map(task => { 
                    task.onFulfilled(this.value);
                });
            });
        }
    }

    reject(reason) {
        if (this.status == 'pending') {
            this.value = reason;
            this.status = 'rejected';
            setTimeout(() => { // 增加异步执行逻辑
                this.thenCbQueue.map(task => {
                    task.onReject(reason); 
                });
            });
        }
    }

    then(onFulfilled, onReject) {
        if (typeof onFulfilled !== 'function') {
            onFulfilled = () => this.value // 往下传递 被下面res接收
        }
        
        if (typeof onReject !== 'function') {
            onReject = () => this.value // 往下传递 被下面res接收
        }
        
        // 这里判断 实例调用.then不能返回自身实例
        let promiseInstance = new _Promise((resolve, reject) => {
            setTimeout(() => { 
                if (this.status == 'pending') {
                    this.thenCbQueue.push({ onFulfilled: val => {
                        // 因为setTimeout是异步的 所以可以读到实例..
                        this.parse(promiseInstance, onFulfilled(val), resolve, reject);
                    }, onReject: reason => {
                        this.parse(promiseInstance, onReject(reason), resolve, reject);
                    } }); 
                } 
    
                if (this.status == 'fulfilled') {
                   this.parse(promiseInstance, onFulfilled(this.value), resolve, reject);
                } 
                
                if (this.status == 'rejected') {
                   this.parse(promiseInstance, onReject(this.value), resolve, reject);
                }
            })
        })
        
        return promiseInstance;
    }
    
    
    parse(instance, res, resolve, reject) {
        // 如果实例和.then方法返回的实例一样 报错
        if (instance == res) {
            throw new TypeError('Chaining cycle detected');    
        }
        try {
            // 注意 then返回值的promise状态默认是成功的
            if (res instanceof _Promise) {
                // res 是 _Promise的实例
                res.then(val => resolve(val), reason => reject(reason))
            } else {
                resolve(res);   
            }
        } catch(e) {
            reject(e); // onReject -> reject 
        }
    }
    
    // 静态方法resolve
    static resolve(value) {
        return new _Promise((resolve, reject) => {
            if (value instanceof _Promise) {
                // value 是 _Promise的实例 返回结果成功或者失败依赖value的状态
                value.then(val => resolve(val), reason => reject(reason))
            } else {
                resolve(value);   
            }
        });
    }
    
    // 静态方法reject实现较为简单
    static reject(value) {
        return new _Promise((resolve, reject) => {
            reject(value);   
        });
    }
    
    // 传进来的是一个promise实例列表
    static all(promises) {
        return new _Promise((resolve, reject) => {
            const successPromiseSet = []; // 成功的结果数组
            
            promises.forEach(promise => {
                promise.then(val => {
                    successPromiseSet.push(val);
                    
                    // 如果结果的数量 = 传递的promise数量 则返回结果集
                    if (successPromiseSet.length == promises.length) {
                        resolve(successPromiseSet);
                    }
                }, reason => {
                    reject(reason);
                });
            });
        })
    }
    
    // 传进来的也是一个promise实例列表 
    // promise 一个状态改变 就不能再次更改
    static race(promises) {
        return new _Promise((resolve, reject) => {
            promises.forEach(promise => {
                promise.then(val => resolve(val), reason => reject(reason));
            });
        });
    }
}

// 测试
var u1 = new _Promise(resolve => {
    setTimeout(() => {
        resolve('ys');
    }, 200);
});


var u2 = new _Promise((resolve, reject) => {
    setTimeout(() => {
        reject('笑嘻嘻');
    }, 1000)
});

_Promise.race([u1, u2]).then(val => console.log('race winner is : ' + val), reason => console.warn('reject: race winner is : ' + reason));
// race winner is : ys

var u1 = new _Promise(resolve => {
    setTimeout(() => {
        resolve('ys');
    }, 2000);
});


var u2 = new _Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('笑嘻嘻');
    }, 1000)
});

_Promise.race([u1, u2]).then(val => console.log('race winner is : ' + val), reason => console.warn('reject: race winner is : ' + reason));
// race winner is : 笑嘻嘻