实现Promise

139 阅读2分钟

基本要求

1.new Promise 接受一个函数func

2.函数func接收两个参数resolve和reject, 调用resolve的时候,把Promise状态变为成功 调用reject的时候,把Promise状态变为失败

3.Promise对象的then方法来注册成功状态或失败状态要执行的函数

4.实现一个Promise对象可以多次调用then方法

5.then函数的链式操作 p.then().then().then(); then()执行后返回的是一个Promise对象

6.thenable 拥有then方法的对象或者函数

7.当给resolve传入一个Promise对象后,只有等Promise对象传入成功后,resolve才会成功

8.resolve要接收的参数 (1)简单值 (2)thenable对象 (3)函数---用的很少,暂不讨论

Promise.all, Promise.resolve等实现后面补上。先消化一下。

class customPromise{
 constructor(func){
   this._status = 'pending';
   //记录resolve函数传过来的参数
   this._value = null;
   //记录reject函数传过来的参数
   this.error = null;
   //收集成功状态要执行的函数
   this.resolvedArr = [];
   //收集失败状态要执行的函数
   this.rejectedArr = [];
   this._hander(func);
 }
 //判断value有没有then函数,并拿出then函数
 _getThen(value){
   let type = typeof value;
   if(value && (type === 'object' || type === 'function')){
     let then;
     if(then = value.then){return then;}
   }
   return null
 }
 // 接受外部传入的函数,调用外部传入的函数
 _hander(func){
   let done = false;  //让函数只执行一次
   func((value)=>{
     if(done) return;
     done = true;
      let then = this._getThen(value);
     if(then){
             //拿到对象的then之后,怎么知道这个promise对象完成了
             //在then函数上注册成功和失败函数就可以
      return this._hander(then.bind(value))
     }
      this._resolve(value)
   },(error)=>{
   if(done) return;
     done = true;
     let then = this._getThen(error);
     if(then){
             //拿到对象的then之后,怎么知道这个promise对象完成了
             //在then函数上注册成功和失败函数就可以
      return this._hander(then.bind(error))
     }
      this._reject(error)
   });
 }
 _resolve(value){
   setTimeout(()=>{
       //状态改为成功
   this._status = 'fulfilled'
   this._value = value
   //执行所有成功的函数
   this.resolvedArr.forEach(item=>item(this._value))
   },0)
 }
 _reject(error){
  setTimeout(()=>{
     //状态改为失败
   this._status = 'rejected'
   this.error = error
   //执行所有成功的函数
   this.rejectedArr.forEach(item=>item(this._error))
  },0)
 }
 //收集注册成功或者失败状态要执行的函数,在pending阶段收集
 _done(resolvedFunc,rejectedFunc){
   resolvedFunc = typeof resolvedFunc === 'function'?resolvedFunc:null
   rejectedFunc = typeof rejectedFunc === 'function'?rejectedFunc:null
   if(this._status === 'pending'){
    if(resolvedFunc) this.resolvedArr.push(resolvedFunc)
    if(rejectedFunc) this.rejectedArr.push(rejectedFunc)
   } else if(this._status === 'fulfilled' && resolvedFunc){ //直接执行
     resolvedFunc(this._value);
   } else if(this._status === 'rejected' && rejectedFunc){ //直接执行
     rejectedFunc(this._error);
   } 
 }
 
 then(resolvedFunc,rejectedFunc){
    //this._done(resolvedFunc,rejectedFunc)
    return new customPromise((resolve,reject)=>{
      return this._done(
        (value)=>{
          if(typeof resolvedFunc !=='function'){
            return resolve(value)
          }
          resolve(resolvedFunc(value))
        },
        (error)=>{
          if(typeof resolvedFunc !=='function'){
            return reject(value)
          }
          reject(rejectedFunc(error))
        }
      )
    })
 }
}