美文网首页
实现Promise类,其中发现的细节

实现Promise类,其中发现的细节

作者: strong9527 | 来源:发表于2018-09-26 10:44 被阅读13次

    Promise 源码学习笔记

    在学习Promise中让我印象最深的就是他的 .then方法,所以我非常想知道它的实现的原理。所以我到github上找了相关的实现代码。

    github上的代码地址


    下面是最核心的两段代码:Promise的构造函数,和then方法的定义
    
    function Promise(fn) {
      if (typeof this !== 'object') {
        throw new TypeError('Promises must be constructed via new');
      }
      if (typeof fn !== 'function') {
        throw new TypeError('Promise constructor\'s argument is not a function');
      }
      this._deferredState = 0;
      this._state = 0;
      this._value = null;
      this._deferreds = null;
      if (fn === noop) return;
      doResolve(fn, this);
    }
    
    Promise._onHandle = null;
    Promise._onReject = null;
    Promise._noop = noop;
    
    Promise.prototype.then = function(onFulfilled, onRejected) {
      if (this.constructor !== Promise) {
        return safeThen(this, onFulfilled, onRejected);
      }
      var res = new Promise(noop);
      handle(this, new Handler(onFulfilled, onRejected, res));
      return res;
    };
    
    
    

    其中我们可以看到then方法中的
      var res = new Promise(noop);
      handle(this, new Handler(onFulfilled, onRejected, res));
      return res;
    
    

    这三行代码就说明了Promise的每一次then方法都会重新构造一个Promise对象,而不是在原有对象上修改。为了证明这一点,我写了一个小demo:

    
    var promise = new Promise(function(resolve,reject){
      resolve()
    })
    
    var a = promise
    var b = promise.then(function() {
    })
    
    console.log( a === b ) //false
    
    //证明我们的猜想是正确的
    
    
    

    我觉得设计者这么做是因为Promise的定义,在阮一峰的相关文档中,我们可以看到

    • Promise对象有以下两个特点。(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:Pending(进行中)、Resolved(已完成,又称 Fulfilled)和Rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。
    • 一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从Pending变为Resolved和从Pending变为Rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。
    因为在Promise定义的回调函数是可以返回另一个Promise的,如果不新构造一个对象,那么将改变原有Promise对象的状态,这是和定义想反的。(当然这只是我的一个猜想。)

    在这里不便把所有源码都展开但是可以将then函数调用其他函数的大概流程图画一下

    graph LR
    then-->handle
    handle-->handleResovled
    handleResovled-->resolve
    

    handle函数的大概作用就是根据Promise对象回调函数的返回值,修改当前Promise对象,其中有一行关键的代码

    
    while (self._state === 3) {
        self = self._value;
    }
    
    
    

    self代表当前Promise对象,而State === 3 代表着当前Promise对象回调函数返回值是一个Promise对象,在这里作者直接将当前Promise对象,替换成了回调函数返回的新Promise进行后续操作。


    而后面两个函数大概作用就是,将回调函数返回值赋给新的Promise,就不在多说

    相关文章

      网友评论

          本文标题:实现Promise类,其中发现的细节

          本文链接:https://www.haomeiwen.com/subject/vabmxftx.html