一个简洁的promise实现

349 阅读2分钟

js的promise处理异步回调已经是一个很普通的功能了,现在比较主流的浏览器都支持原生的promise,下面使用es6的class语法实现一个比较简易的promise。

1 定义一个Promise的类,constructor方法会在实例化的时候执行,传入一个回调函数给this.calllback。

2 then方法接收两个参数,分别是成功的方法和失败的方法,保存在实例属性fullfilledFunc和errorFunc中

3 error 方法接收一个参数,实际上then方法的传递的第二个参数做的同样的事情,只不过是提供了多种途径来传递一个错误回调

4 在then 实例方法或者error实例方法绑定完成回调函数,就可以执行调this.callback,并且把then和error绑定的方法传给回调,

class Promise1{  constructor(callback) { 
  this.callback=callback;
  this.fullfilledFunc; 
  this.errorFunc; 
 }
 then(fullfilled,errorFunc){ 
  this.fullfilledFunc=fullfilled || (()=>{});
  this.errorFunc=errorFunc || (()=>{});           this.callback(this.fullfilledFunc,this.errorFunc)       
 return this; 
 }
 error(errorFunc){ 
  this.errorFunc=errorFunc || (()=>{});           this.callback(this.fullfilledFunc,this.errorFunc)  
 return this; 
}

使用如下:

var fn =new Promise((resolve,reject)=>{  setTimeout(()=>{ 
 // resolve("完成") 
 reject("发生了一个的错误")    },1000)
})
fn.then((val)=>{ 
 console.log(val) 
}).error(()=>{ 
 console.log('发生了一个错误')
})

上面的实现,只是使用的es6类及函数式编程的一些思想,实现了一个简易的promise,原生的promise是有状态的。体现在使用上就是,resolve只能执行一次,执行完成状态就是完成态,或者reject执行就是失败态。而上面的实现没有办法做到这一点,因为resolve和reject的执行,在promise内部是不知道的。所以要通过下面的方式实现有状态的promise。


1 在promise类中定义一个状态,this.state

2 定义实例方法handleFullfill,判断状态是否改变,如果没有改变,执行this.fullfillFunc,改变状态为fullfilled

3 定义实例方法handleError,判断状态是否改变,如果没有改变,执行this.errorFunc,改变状态为errored

    这样做的好处就是把resolve和reject的定义放在promise实例方法中,在执行时,promise内部可以改变状态

class Promise {  constructor(callback) { 
  this.callback=callback; 
  this.fullfillFunc; 
  this.errorFunc; 
  this.state; 
 } 


 then(fullfilled,errorFunc){ 
  this.fullfillFunc=fullfilled || (()=>{}); 
  this.errorFunc=errorFunc || (()=>{});   
  this.callback(this.handleFullfill.bind(this),this.handleError.bind(this)) 
  return this; 
 } 
 error(errorFunc){ 
  this.errorFunc=errorFunc || (()=>{});                     
  this.callback(this.handleFullfill.bind(this),this.handleError.bind(this))          
  return this; 
 } 
 handleFullfill(){ 
  if(!this.state){ 
   let params = [].slice.call(arguments,0) 
   this.state="fullfilled" 
   this.fullfillFunc.apply(null,params); 
  } 
 } 
 handleError(){ 
  if(!this.state){ 
   let params = [].slice.call(arguments,0,1) 
   console.log(new Error(params[0])) 
   this.state="errored" 
   this.errorFunc.apply(null,params);; 
  } 
 }
}



以上就是实现了一个带状态的Promise,虽然简介,但是从中可以学习到js编程的一些特点