Rumah > hujung hadapan web > tutorial js > es6-promise源码的分析

es6-promise源码的分析

不言
Lepaskan: 2019-03-23 10:03:18
ke hadapan
2973 orang telah melayarinya

本篇文章给大家带来的内容是关于es6-promise源码的分析,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

主要逻辑:

本质上还是回调函数那一套。
通过_subscribers的判断完成异步和同步的区分。
通过 resolve,reject -> publish -> invokeCallback -> resolve,reject的递归和下一条then的parent是上一条的child来完成then链的流转

同步情况下函数流转: constructor -> resolver -> publish -> then -> invokeCallback 
异步情况下函数流转: constructor -> then -> resolver -> publish -> invokeCallback

主要函数解析

1、constructor
作用: 把resolve,reject绑定到 resolver上-

1

2

3

4

5

6

7

8

9

10

11

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();

    }

  }

Salin selepas log masuk

2 then
作用: 把回调函数绑定在_subscribers上,catch和finally本质是then的语法糖
 _subscribers的参数是一个数组,[0]是他的child,绑定下一个then链的parent,用于publish递归调用, 第二个是resolve 回调, 第三个是reject回调

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

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;

}

Salin selepas log masuk

3 publish
作用: resolve,reject的触发会调用publish,publish继续调用invokeCallback,通过返回值继续调用resolve,reject,形成一个递归,完成then链的流转

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

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;

}

Salin selepas log masuk

tip:
finally的callback是没有返回参数的,基于

1

2

return promise.then(value => constructor.resolve(callback()).then(() => value),

                         reason => constructor.resolve(callback()).then(() => { throw reason; }));

Salin selepas log masuk

本篇文章到这里就已经全部结束了,更多其他精彩内容可以关注PHP中文网的JavaScript视频教程栏目!

Atas ialah kandungan terperinci es6-promise源码的分析. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan