深入 Promise(一)——Promise 实现详解

if (typeof Promise === 'undefined') {
     
  return
} 

实现 Promise/A+ 规范的库有很多,lie 是一个精简的实现 Promise/A+ 的库,并且通过了 Promise/A+ 专门的测试集,但 lie 的代码写的有点绕,我在 lie 的代码基础上进行了修改,使之更容易阅读和理解,并发布了 appoint 模块供大家参考。

Promise/A+ 规范

Promise 规范有很多,如 Promise/A,Promise/B,Promise/D 以及 Promise/A 的升级版 Promise/A+,有兴趣的可以去了解下,最终 ES6 中采用了 Promise/A+ 规范。在讲解 Promise 实现之前,当然要先了解 Promise/A+ 规范。Promise/A+ 规范参考:


注意:没有特殊说明以下 promise 均指代 Promise 实例。

规范虽然不长,但细节也比较多,我挑出几个要点简单说明下:

  1. Promise 本质是一个状态机。每个 promise 只能是 3 种状态中的一种:pending、fulfilled 或 rejected。状态转变只能是 pending -> fulfilled 或者 pending -> rejected。状态转变不可逆。
  2. then 方法可以被同一个 promise 调用多次。
  3. then 方法必须返回一个 promise。规范里没有明确说明返回一个新的 promise 还是复用老的 promise(即 return this),大多数实现都是返回一个新的 promise,而且复用老的 promise 可能改变内部状态,这与规范也是相违背的。
  4. 值穿透。下面会细讲。

从头实现 Promise

我们知道 Promise 是一个构造函数,需要用 new 调用,并有以下几个 api:

function Promise(resolver) {}

Promise.prototype.then = function() {}
Promise.prototype.catch = function() {}

Promise.resolve = function() {}
Promise.reject = function() {}
Promise.all = function() {}
Promise.race = function() {}

下面我们以 appoint 为最终目标,开始一步一步构建完整的 Promise 实现。

'use strict';

var immediate = require('immediate');

function INTERNAL() {}
function isFunction(func) {
     
  return typeof func === 'function';
}
function isObject(obj) {
     
  return typeof obj === 'object';
}
function isArray(arr) {
     
  return Object.prototype.toString.call(arr) === '[object Array]';
}

var PENDING = 0;
var FULFILLED = 1;
var REJECTED = 2;

module.exports = Promise;

function Promise(resolver) {
     
  if (!isFunction(resolver)) {
     
    throw new TypeError('resolver must be a function');
  }
  this.state = PENDING;
  this.value = void 0;
  this.queue = [];
  if (resolver !== INTERNAL) {
     
    safelyResolveThen(this, resolver);
  }
}
immediate 是一个将同步转异步执行的库。INTERNAL 就是一个空函数,类似于一些代码库中的 noop。定义了 3 个辅助函数:isFunction、isObject 和 isArray。定义了 3 种状态:PENDING、FULFILLED 和 REJECTED。safelyResolveThen 后面讲。promise 内部有三个变量:
  1. state: 当前 promise 的状态,初始值为 PENDING。状态改变只能是 PENDING -> FULFILLED 或 PENDING -> REJECTED。
  2. value: 当 state 是 FULFILLED 时存储返回值,当 state 是 REJECTED 时存储错误。
  3. queue: promise 内部的回调队列,这是个什么玩意儿?为什么是一个数组?

Promise 实现基本原理

先看一段代码:

var Promise = require('appoint')
var promise = new Promise((resolve) => {
     
  setTimeout(() => {
     
    resolve('haha')
  }, 1000)
})
var a = promise.then(function onSuccess() {})
var b = promise.catch(function onError() {})
console.log(require('util').inspect(promise, {
      depth: 10 }))
console.log(promise.queue[0].promise === a)
console.log(promise.queue[1].promise === b)
打印出:
Promise {
     
  state: 0,
  value:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值