Promise的实现原理(三)
1.Promise 实现原理
1.1 Promise 实现原理之链式调用
1.1.1 基础用法
const p =new Promise((resolve,reject)=>{
resolve('成功')//这里得成功会调用下一个.then里的res回调函数
reject('失败')//这里得失败会调用下一个.then里的err回调函数
})
const p1 = p.then(res=>{
return res // 这里return值会在下一个.then中data回调中
},(err)=>{
return err //这里return值也会在下一个.then中data回调中
})
p1.then((data)=>{
console.log('data',data);
},(err)=>{
// 这里得err 是报的上一个.then 执行中的错误 例如:p.then((res)=>{return new Error('错误')})
})
1.1.1.2 实现思路
问题1:为什么可以连续(点).then,什么东西可以(点).then?
答案:无非就是在实现then 方法的时候 在返回一个新的Promise
问题2:当前then的中数据,如何传到下一个Promise的then 中?
答案:取到当前的值,调用新的Promise 的resolve 方法,就是值传到下一个Promise的then中了么;
1.1.1.3 具体实现
class Mypromise {
// executor 执行者,也就是调用方传过来的函数,他是立即执行的
constructor(executor){
// 状态设置,因为promise 的状态是一旦改变就不允许返回的,我们已0为初始化状态
this.stateus= 0;
// 异步的核心思想就是发布订阅,首先创建两个数组,分别来存储成功回调,以及失败的回调
this.successArray = [];
this.errorArray = [];
// executor又有两个回调函数,一个成功的函数resolve,一个失败的状态reject,首先定义这两个函数
// 使用者传回成功的value值
const resolve = (value)=>{
// 因为promise 的状态是不可逆的,因此这里需要更改status 的状态值
// 用户在.then 的时候,需要在把value值返回给用户,因此要把value暂存一下
this.successValue = value;
this.stateus=1;
// 循环调用.then时的回调函数
this.successArray.forEach(fn=>fn())
}
// 使用者传回失败的value值
const reject= (value)=>{
// 同上
this.errorValue = value;
this.stateus=2;
// 循环调用.then时的回调函数
this.successArray.forEach(fn=>fn())
}
executor(resolve,reject);
}
// 新定义的方法,处理链式调用
resolvePromise(p2,x,resolve,reject){
// 这里的x 就是then函数中的res(成功回调函数)回调函数的return 值,它可能是一个普通类型,可 能又是一个promise
if(typeof x === 'object'&&x!==null){
if(typeof x ==='function'){
// 如果他是一个promise 我们取到它的值
const then = x.then;
if(then){
//这里的x 就是return 出来的promise
then.call(x,(data)=>{
//这里的data可能是个普通值又有可能是个promise
this.resolvePromise(p2,data,resolve,reject)
},(error)=>{
reject(error)
})
}
}
}else{
// 如果是个普通值,我们就把它返回出去,不管成功还是失败
resolve(x)
}
}
// success,error是用户传过来的回调函数
then(success,error){
// 新增代码,修改原来的then 方法
const p2 = new Mypromise((resolve,reject)=>{
// 因为promise 是一旦成就不允许失败的,或者一旦失败不允许成功,所以这里要判断一下
if(this.stateus===1){
// 因为promise中的then 是微任务,所以这里也行要改造一下,我这里用一个宏任务代替settimeout
setTimeout(()=>{
// 这里还应该加一些try catch 的,我这里就省略了
// 如何把当前的值,传给下一个new promise 中的then中呢;实现如下
const x = success(this.successValue);
// 接下来我们单独写一个方法来处理这部分
this.resolvePromise(p2,x,resolve,reject)
},0)
}
if(this.stateus===2){
setTimeout(()=>{
// 这里还应该加一些try catch 的,我这里就省略了
const x = error(this.errorValue);
this.resolvePromise(p2,x,resolve,reject)
},0)
}
// 当用户调用.then 时,我们的status 处于0的状态
if(this.stateus===0){
// 这里我们push 一个函数,是因为我们可以在这个函数中可以扩展一些东西
setTimeout(()=>{
this.successArray.push(()=>{
// 这里还应该加一些try catch 的,我这里就省略了
const x = success(this.successValue);
this.resolvePromise(p2,x,resolve,reject)
});
},0)
setTimeout(()=>{
this.errorArray.push(()=>{
// 这里还应该加一些try catch 的,我这里就省略了
const x = error(this.errorValue);
this.resolvePromise(p2,x,resolve,reject)
});
},0)
}
})
return p2 //此时return 出去一个新的Promise,即可实现链式调用
}
}
到这里里基本上一个简版的Promise 完成了。
Promise的实现原理(四)写le一些Promise.all 以及Promise.race的基本实现;