上一节我们已经对promise的基本使用方法有一定的了解了,那么接下来我们可以自己尝试实现promise的内部机制,今天,就跟我一起,一步一步来手写一个promise吧。
一、首先实现resolve和reject可以被调用,但不能被同时调用
constructor(excutor){
let this_status = PROMISE_STATUE_PENDING;
this.value= undefined;
this.reason = undefined;
const resolve = (value)=>{
if(this_status===PROMISE_STATUE_PENDING)
{
this_status=PROMISE_STATUE_FULFILLED
this.value= value;
console.log("resolve被调用")
}
};
const reject =(reason)=>{
if(this_status===PROMISE_STATUE_PENDING)
{
this_status=PROMISE_STATUE_REJECTED
this.reason=reason;
console.log(reason,"reject被调用")
}
}
excutor(resolve,reject)
}
}
const promise = new CTPromise((resolve,reject)=>{
console.log("状态pendding")
// resolve()
reject(1111)
})
二、promise中then方法的实现
1、then方法的基础调用
const PROMISE_STATUE_PENDING ='pending'
const PROMISE_STATUE_FULFILLED ='fulfilled'
const PROMISE_STATUE_REJECTED ='rejected'
class CTPromise{
constructor(excutor){
let this_status = PROMISE_STATUE_PENDING;
this.value= undefined;
this.reason = undefined;
const resolve = (value)=>{
if(this_status===PROMISE_STATUE_PENDING)
{
this_status=PROMISE_STATUE_FULFILLED
queueMicrotask(()=>{
this.value= value;
this.onfulfilled(this.value)
})
//这样会导致onfulfilled调用失败,因为construtor会立即执行,而这个时候then方法还没开始赋值,
// 所以会导致this_onfulfilled is not function,需要在resolve中加入一个异步。等到先then方法先作用,再去resolve或reject中调用函数
}
};
const reject =(reason)=>{
if(this_status===PROMISE_STATUE_PENDING)
{
this_status=PROMISE_STATUE_REJECTED
queueMicrotask(()=>{
this.reason=reason;
this.onrejected(this.reason)
})
}
}
excutor(resolve,reject)
}
then(onfulfilled,onrejected){
this.onfulfilled=onfulfilled
this.onrejected=onrejected
}
}
const promise = new CTPromise((resolve,reject)=>{
console.log("状态pendding")
resolve(22222)
reject(1111)
})
promise.then((res)=>{console.log("res:",res)},(err)=>{
console.log("err:",err)
})
2、分别调用多次then方法的实现
多次调用then方法中的resolve函数和reject函数,就是把传进来的函数放入到一个数组中,执行时对这个数组进行遍历,依次执行。
//1.定义一个数组
this.onfulfilledFns=[]
this.onrejectedFns=[]
//2.将多次调用的then中的resolve函数和reject函数放入数组中
then(onfulfilled,onrejected){
this.onfulfilledFns.push(onfulfilled)
this.onrejectedFns.push(onrejected)
}
//3.调用resolve时,遍历onfulfilledFns中的函数依次执行
this.onfulfilledFns.forEach(fn=>{
fn(this.value)
//4.调用reject时,遍历onrejectedFns中的函数依次执行
this.onrejectedFns.forEach(fn => {
fn(this.reason)
3、实现在promise确定状态之后,再次调用then()
1.在接收函数时,加上一个判断条件
// 如果then调用的时候状态已经敲定,且传进来的函数有值的情况下
if(this_status===PROMISE_STATUE_FULFILLED&&onfulfilled){
onfulfilled(this.value)
}
if(this_status===PROMISE_STATUE_REJECTED&&onrejected){
onrejected(this.reason)
}
if(this_status===PROMISE_STATUE_PENDING){
this.onfulfilledFns.push(onfulfilled)
this.onrejectedFns.push(onrejected)
}
}
}
2.如果函数状态不等于pending时,直接return
4、then后面可以接着调用then,实现链式调用。
1.在第一次调用then方法后,默认返回的是undefined,只有返回值是promise时,才可以继续调用then,所以需要在then方法中返回一个promise.
then(onfulfilled,onrejected){
// 1.如果then调用的时候状态已经敲定,且传进来的函数有值的情况下
return new CTPromise((resolve,reject)=>{
// resolve(2222)//传入的应该是第一次调用then的时候返回的结果.
if(this_status===PROMISE_STATUE_FULFILLED&&onfulfilled){
onfulfilled(this.value)
}
if(this_status===PROMISE_STATUE_REJECTED&&onrejected){
onrejected(this.reason)
}
if(this_status===PROMISE_STATUE_PENDING){
this.onfulfilledFns.push(onfulfilled)
this.onrejectedFns.push(onrejected)
}
})
}
对不起,xdm,写不下去了,大家慢慢领悟