Home  >  Article  >  Web Front-end  >  Analysis of es6-promise source code

Analysis of es6-promise source code

不言
不言forward
2019-03-23 10:03:182764browse

The content of this article is about the analysis of es6-promise source code. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.

Main logic:

Essentially, it’s still the callback function.
The distinction between asynchronous and synchronous is completed through the judgment of _subscribers.
Complete the flow of the then chain through resolve, reject -> publish -> invokeCallback -> resolve, the recursion of reject, and the parent of the next then is the child of the previous one.

Function in the case of synchronization Flow: constructor -> resolver -> publish -> then -> invokeCallback
Function flow in asynchronous situations: constructor -> then -> resolver -> publish -> invokeCallback

Main function analysis

1. Constructor
Function: Bind resolve and reject to resolver-

constructor(resolver) {
    this[PROMISE_ID] = nextId();
    this._result = this._state = undefined;
    this._subscribers = [];
    <!-- 判断resolver是不是一个空对象 -->
    if (noop !== resolver) {
      typeof resolver !== 'function' && needsResolver();
      <!-- 把resolve,reject绑定到 resolver上-->
      this instanceof Promise ? initializePromise(this, resolver) : needsNew();
    }
  }

2 then
Function: Bind callback The function is bound to _subscribers. Catch and finally are essentially syntactic sugar for then
The parameter of _subscribers is an array, [0] is its child, bound to the parent of the next then chain, and is used for publish recursive calls. The second is the resolve callback, and the third is the reject callback

export default function then(onFulfillment, onRejection) {
  const parent = this;
  <!-- 用于then链的返回值,下一条then就是当前parent的child -->
  const child = new this.constructor(noop);

  if (child[PROMISE_ID] === undefined) {
    makePromise(child);
  }

  const { _state } = parent;
 <!-- 判断_state的状态,是不是PENDING -->
  if (_state) {
    const callback = arguments[_state - 1];
    asap(() => invokeCallback(_state, child, callback, parent._result));
  } else {
    subscribe(parent, child, onFulfillment, onRejection);
  }

  return child;
}

3 publish
Function: resolve, the trigger of reject will call publish, publish will continue to call invokeCallback, and return the value Continue to call resolve and reject to form a recursion and complete the flow of the then chain

function publish(promise) {
  let subscribers = promise._subscribers;
  let settled = promise._state;

  if (subscribers.length === 0) { return; }

  let child, callback, detail = promise._result;

  for (let i = 0; i < subscribers.length; i += 3) {
    child = subscribers[i];
    callback = subscribers[i + settled];

    if (child) {
      invokeCallback(settled, child, callback, detail);
    } else {
      callback(detail);
    }
  }

  promise._subscribers.length = 0;
}

tip:
finally callback has no return parameters, based on

return promise.then(value => constructor.resolve(callback()).then(() => value),
                         reason => constructor.resolve(callback()).then(() => { throw reason; }));

This article has ended here. For more other exciting content, you can pay attention to the JavaScript Video Tutorial column on the PHP Chinese website!

The above is the detailed content of Analysis of es6-promise source code. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:segmentfault.com. If there is any infringement, please contact admin@php.cn delete