手把手教你手写promise

98 阅读2分钟

上一节我们已经对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,写不下去了,大家慢慢领悟