Skip to the content.

Promise实现

Promise标准

构造函数

创建Promise实例的形式

var promise = new Promise(function (resolve, reject) {}/* executor */)

定义Promise

function noop() { } // 工具函数 空函数
// Polyfill for Function.prototype.bind
function bind(fn, thisArg) {
  return function () {
    return fn.apply(thisArg, arguments)
  }
}
// 处理函数
function handle(deferred, self) {
  while (self._status === 3) {
    self = self._value
  }
  if (self._status === 0) {
    self._deferreds.push(deferred)
    return
  }
  self._handled = true
  Promise._immediateFn(function () {
    var cb = self._status === 1 ? deferred.onFulfilled : deferred.onRejected
    if (cb === null) {
      (self._status === 1 ? resolve : reject)(self._value, deferred.promise)
      return
    }
    var ret
    try {
      ret = cb(self._value)
    } catch (e) {
      reject(e, deferred.promise)
      return
    }
    resolve(ret, deferred.promise)
  })
}

// 执行被推进promise执行数组的函数
function finale(self) {
  // rejected状态, 且执行数组中不存在函数
  if (self._status === 2 && self._deferreds.length === 0) {
    Promise._immediateFn(function () {
      if (!self._handled) {
        Promise._unhandledRejectionFn(self._value)
      }
    })
  }
  for (var i = 0, len = self._deferreds.length; i < len; i += 1) {
    handle(self._deferreds[i], self)
  }
  self._deferreds = null // 回收
}
// Promise reject
function reject(value, self) {
  self._status = 2
  self._value = value
  finale(self)
}
// Promise resolve
function resolve(value, self) {
  try {
    if (value === self) {
      throw new TypeError('A Promise cannot be resolved with itself')
    }
    // resolve处理的值, value可能为promise实例, 或者为其它实现
    if (value && (typeof value === 'object' || typeof value === 'function')) {
      var then = value.then
      if (value instanceof Promise) { // 本身的promise实例
        self._status = 3
        self._value = value
        finale(self)
        return
      } else if (typeof then === 'function') { // 其它promise实例
        doExecutor(bind(then, value), self)
        return
      }
    }
    self._status = 1
    self._value = value
    finale(self)
  } catch (e) {
    reject(e, self)
  }
}
// 函数, reject或者resolve只执行一次, self为promise实例
function doExecutor(executor, self) {
  var done = false
  try {
    executor(
      function (value) {
        if (done) {
          return;
        }
        done = true
        resolve(value, self)
      },
      function (reason) {
        if (done) {
          return;
        }
        done = true
        reject(reason, self)
      }
    )
  } catch (err) {
    if (done) {
      return;
    }
    done = true
    reject(err, self)
  }
}

function Promise(executor) {
  if (!(this instanceof Promise)) {
    throw new TypeError('Promise must be constructed via new')
  }
  if (typeof executor !== 'function') {
    throw new TypeError('Promise executor must be a function')
  }
  this._status = 0 // 状态值0-3
  this._value = undefined // 回调值值
  this._deferreds = [] // 处理数组
  this._handled = false // 初始处理状态
  doExecutor(executor, this) // 执行器
}
// 处理器
function Handler(onFulfilled, onRejected, promise) {
  this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null
  this.onRejected = typeof onRejected === 'function' ? onRejected : null
  this.promise = promise
}

// 实现then方法, 主要在于返回值为新的promise对象
Promise.prototype.then = function (onFulfilled, onRejected) {
  var prom = new this.constructor(noop)

  handle(new Handler(onFulfilled, onRejected, prom), this)
  return prom
}

// 事件循环当前回合结束时调用的函数. polyfill
Promise._immediateFn = (typeof setImmediate === 'function' && function (fn) {
  setImmediate(fn) // Nodejs的立即调用定时器函数
}) ||
  function (fn) {
    setTimeout(fn, 0)
  }
// promise error未捕获
Promise._unhandledRejectionFn = function _unhandledRejectionFn(err) {
  if (typeof console !== 'undefined' && console) {
    console.warn('Possible Unhandled Promise Rejection:', err); // eslint-disable-line no-console
  }
};

Question:下面四个使用promise的语句之间的不同点在哪儿?

doSomething().then(() => {
  return doSomethingElse();
})

doSomething().then(() => {
  doSomethingElse();
});

doSomething().then(doSomethingElse());

doSomething().then(doSomethingElse);

Answer: #1

doSomething().then(() => {
  return doSomethingElse();
}).then(finalHandler);

答案:

doSomething |———| doSomethingElse(undefined) |————| finalHandler(resultOfDoSomethingElse) |——————|

#2

doSomething().then(() => {
  doSomethingElse();
}).then(finalHandler);

答案:

doSomething |—————–| doSomethingElse(undefined) |——————| finalHandler(undefined) |——————|

#3

doSomething().then(doSomethingElse())
.then(finalHandler);

答案

doSomething |—————–| doSomethingElse(undefined) |———————————| finalHandler(resultOfDoSomething) |——————|

#4

doSomething().then(doSomethingElse)
.then(finalHandler);

答案

doSomething |—————–| doSomethingElse(resultOfDoSomething) |——————| finalHandler(resultOfDoSomethingElse) |——————|