Promise实现原理学习笔记

       Promise 是异步编程的一种解决方案,用于解决传统编程中的回调地狱问题。ES6对其标准用法进行了统一,并原生提供了Promise对象。Promise对象有三种状态:等待态(Pending)、执行态(Fulfilled)和拒绝态(Rejected),且状态的转换是不可逆的,只能由Pending转换为FulfilledRejected,而FulfilledRejected之间是不能互相转换的

       Promise对象表示一个异步操作的执行结果,通过then方法与其进行交互,then方法使用两个回调函数作为参数,用于接收Promise成功执行的结果或者被拒绝执行的原因。

基本用法:

function onFulfilled(value) {
  console.log(value)
}
function onRejected(error) {
  console.log(error)
}

const promise = new Promise(function(resolve, reject) {
  // ...异步操作
  if (/* 操作成功 */) {
    resolve(value);
  } else {
    reject(error);
  }
});

promise.then(onFulfilled, onRejected);

上面就是Promise的一个基本用法,更详细的使用说明请参考阮一峰ECMAScript 6入门之Promise对象

原理说明:

  通过上面的基本用法可以看出,Promise是一个构造函数,该构造函数接收一个函数作为参数,为了便于说明我们把该函数命名为executorexecutor有两个参数resolvereject,这两个参数也都是函数。Promise对象上还必须有一个then方法,该方法也接收两个函数作为参数。

基于以上说明,我们先给出一个Promise构造函数的简单实现框架如下:

function Promise(executor) {
  function resolve(value) {
   }
function reject(error) {
   } executor(resolve, reject) } Promise.prototype.then
= function(onFulfilled, onRejected) {
}

Promise的核心特点之一就是状态的转换,所以我们要在框架中体现出转换的变化,如下:

function Promise(executor) {
  this.status = 'pending'

  function resolve(value) {
    if(this.status == 'pending') {
      this.status = 'fulfilled'
    }
  }

  function reject(error) {
    if(this.status == 'pending') {
      this.status = 'rejected'
    }
  }

  executor(resolve, reject)
}

Promise.prototype.then = function(onFulfilled, onRejected) {
  if(this.status == 'fulfilled') {
    onFulfilled()
  }

  if(this.status == 'rejected') {
    onRejected()
  }
}

此时该Promise也仅仅只是能够处理同步操作,就是说当我们调用then方法时executor已经处理结束,状态已经由pending转换为fulfilledrejected,但这肯定是不可能的!!!所以在调用then方法时我们还得考虑状态为pending的情况,但是在状态为pending的情况下调用onFulfilledonRejected回调函数是完全没有意义的,所以我们只能先将对应的回调函数缓存起来,等到状态改变之后再调用执行。如下:

function Promise(executor) {
  this.status = 'pending'
  this.value = null
  this.error = null
  this.onFulfilledCallbacks = []
  this.onRejectedCallbacks = []

  function resolve(value) {
    if(this.status == 'pending') {
      this.status = 'fulfilled'
      this.value = value
      this.onFulfilledCallbacks.forEach(function(callback) {
        callback()
      });
    }
  }

  function reject(error) {
    if(this.status == 'pending') {
      this.status = 'rejected'
      this.error = error
      this.onRejectedCallbacks.forEach(function(callback) {
        callback()
      });
    }
  }

  executor(resolve, reject)
}

Promise.prototype.then = function(onFulfilled, onRejected) {
  if(this.status == 'fulfilled') {
    onFulfilled(this.value)
  }

  if(this.status == 'rejected') {
    onRejected(this.error)
  }

  if(this.status == 'pending') {
    this.onFulfilledCallbacks.push(onFulfilled(this.value))
    this.onRejectedCallbacks.push(onRejected(this.error))
  }
}

  至此,一个简单的Promise实现就算完成了,暂时没有考虑一些校验和错误处理。其实核心的实现原理就是状态机制+观察者模式

参考文献:

  1、【翻译】Promises/A+规范

  2、30分钟,让你彻底明白Promise原理

  3、Promise原理详解

猜你喜欢

转载自www.cnblogs.com/fengyuexuan/p/12187810.html