Promise 原理理解

113 阅读2分钟

Promise是异步编程的一种解决方案,其对象有两个特点:

1、 对象的状态不受外界影响

2、 一旦状态改变就不会再变

为了实现Promise,必须清楚Promise个状态 PENDINGFULFILLEDREJECTED,两个值_resolve_(value),reject(reason),为了执行异步操作声明一个回调数组

const PENDING = 'PENDING'
const FULFILLED = 'FULFILLED'
const REJECTED = 'REJECTED'

class myPromise {
  constructor(executor) {
    this.status = PENDING
    this.value = null
    this.reason = null
    this.callbacks = []
    try{
      executor(this.resolve.bind(this),this.reject.bind(this))
    }catch(e){
      this.reject(err)
    }
 }
}

两个回调函数_resolve_(value),reject(reason) 只有在status 的状态发生改变后,这两个回调函数才会执行,由于这两个回调函数都是异步执行,这里用setTimeout模拟

resolve(value) {
  if ( this.status == 'PENDING') {		
    this.status = FULFILLED
    this.value = value
    setTimeout(()=>{
      this.callbacks.map( callback => {
      callback.onFulfilled(this.value)
      })
    })
  }
}
	
reject(reason) {
  if ( this.status == 'PENDING') {
    this.status = REJECTED 
    this.value = reason
    // 执行异步操作
    setTimeout(()=>{
      this.callbacks.map( callback => {
        callback.onRejected(this.value)
      })
    })
  }
}

Promise里面的任务执行了之后会跳转到then函数里进行处理,then函数里有两个回调函数*(onFulfilled,onRejected)*,这两个函数可以被传递也可以不被传递,因此需要判断传入的参数是否为函数进行特殊处理

  • 支持链式调用,所以需要一个为Promise的返回值
  • 在_status_ 为PENDING时,代表Promise里面执行的是异步操作,因此需要将onFulfilledonRejected 这两个函数压入回调数组中用以改变Promise的状态
  • onFulfilledonRejected 这两个函数也是异步执行,这里用setTimeout模拟
then(onFulfilled,onRejected) {
  if ( typeof onFulfilled != 'function') {
    onFulfilled = ()=> this.value
  }
  
  if ( typeof onRejected != 'function') 
    onRejected = ()=> this.value
  }
  
  let promise = new myPromise( (resolve,reject ) => {
  
  // 执行异步操作
    if ( this.status == 'PENDING' ) {
    this.callbacks.push({
    
      onFulfilled: value => {
        this.parse(promise,onFulfilled(value),resolve,reject)			
      },
      onRejected: value => {
      	this.parse( promise,onRejected(value) ,resolve,reject)
      }
    })
  }
	  		
  if ( this.status == 'FULFILLED' ) {
    setTimeout( () => {
      this.parse(promise,onFulfilled(this.value),resolve,reject)
    })
  }
  			
  if ( this.status == 'REJECTED'  ) {
    setTimeout( () => {
      this.parse( promise,onRejected(this.value) ,resolve,reject)	
    })
   }
 })
		
  return promise
}

以下是parse函数,这个函数是每次具体的处理逻辑

parse(promise,results,resolve,reject) {
  if (promise == results) {
    return new TypeError('fail') //此处是为了判断传入的参数是否为当前的Promise对象
  }
  try{
    if ( results instanceof myPromise) {
      results.then(resolve,reject)
    }else {
      resolve(results)
    }
  }catch(e){
    reject(e)
  } 
}

Promise还支持静态调用

Promise.resolve()

Promise.reject()

Promise.all()

Promise.pace()

下面为以上四个静态函数的实现方法

static reslove(value) {
  return new myPromise((resolve,reject) => {
    if (value instanceof myPromise) {
      value.then(resolve,reject)
    }else {
      resolve(value)
    }
  })
}

static reject(value) {
  return new myPromise((resolve,reject) => {
    reject(value)
  })
}

static all(promise) {
  let values = []
  return new myPromise( (resolve,reject) => {
    promise.forEach(pro => {
      pro.then(value => {
      values.push(value)
      if (values.length == promise.length) {
       resolve(values)
      }
      },reason => {
        reject(value)
      })
    })
  })
}

static pace(promise) {
  return new myPromise( (resolve,reject) => {
      promise.forEach(pro => {
      resolve(value)
    },reason => {
      reject(value)	
    })
  })
}