80行代码带你了解 Promise 原理
Promise 构造函数
class LcPromise {
constructor(fn){
this.successList = [];
this.failList = [];
this.state = 'pending';
// fn 的实参是自定义的两个函数
fn(this.resoluveFn.bind(this), this.rejectFn.bind(this))
}
// then 函数的实参在调用时注册
then(successFn, failFn){
if(typeof successFn === 'function'){
this.successList.push(successFn)
}
if(typeof failFn === 'function'){
this.failList.push(failFn)
}
}
catch(failFn){
if(typeof failFn === 'function'){
this.failList.push(failFn)
}
}
// 执行成功时(resolve)调用,
resoluveFn(res){
this.state = 'fullfilled';
this.successList.forEach((item, i) => {
item(res)
})
}
rejectFn(res){
this.state = 'rejected';
this.failList.forEach((item, i) => {
item(res)
// 一旦失败,就不继续执行了!
throw Error(res)
})
}
}
module.exports = LcPromise;
实例调用
const LcPromise = require('./lcPromise');
const fn = (resolve, reject) => {
setTimeout(() => {
// 简单模拟一下多次调用不同结果
const random = Math.random();
if(random > 0.5){
resolve('成功了!')
}else{
reject('失败了!')
}
}, 100);
}
const p1 = new LcPromise(fn);
// 注册执行成功时的执行函数
p1.then((res) => {
console.log(res)
})
p1.then((res) => {
console.log('啊!又注册了一个', + res)
})
// 注册执行失败时的执行函数
p1.catch((err) => {
console.log(err)
})
完事!Promise 再也不“豪横”了!
顺便说一下:then 的第二个参数(failFn)与 catch 有什么区别?
catch 就是 failFn 的语法糖(上面构造函数中也可以看出),集中处理错误,如果你写了 then 函数的第二个参数,如果有错误,就不会走到 catch 中了。
over!