美文网首页源码学习
es6 Promise 学习笔记2 链式调用

es6 Promise 学习笔记2 链式调用

作者: 草祭木初 | 来源:发表于2020-07-17 10:28 被阅读0次

    es6 Promise 学习笔记1 基础代码解析

    这期讲个复杂点的例子 then里的回调返回一个 Promise

    function test () {
      let pms = new Promise((resolve, reject) => {
        // resolve(1)
        // reject(2)
      });
      pms.then((value)=>{
        console.log('this is then 1:',value)
        return new Promise((resolve, reject) => {
            // resolve(3)
            // reject(4)
        });
      }).then((value)=>{
        console.log('this is then 2:',value)
      }).catch ((e)=>{
        console.log('this is catch:',e)
      }).finally(()=>{
        console.log('this is finally:')
      })
    }
    test();
    

    首先回忆一下 _subscribers里现在有几个值, 是下面这样 共12个
    根Promise [then,thenResolve,thenReject, then2,thenResolve2,thenReject2, catch,catchResolve,catchReject,finally,finallyResolve,finallyReject]
    但then 里返回的Promise 的_subscribers 是[]的,因为它没有then catch finally

    第一个then 的执行

    function resolve(promise, value) {
      if (promise === value) {
        reject(promise, selfFulfillment());
      } else if (objectOrFunction(value)) {
    // resolvePromise 传入的参数是一个 对象或者的函数的话
    // 这里判断了一下 他是否有 then 函数, 也就是说 resovle 的参数可以是 另一个Promise
        let then;
        try {
          then = value.then; // 这种value是 Promise 的情况后面我们会讲到
        } catch (error) {
          reject(promise, error);
          return;
        }
        handleMaybeThenable(promise, value, then);
      } else {
        fulfill(promise, value);
      }
    }
     
    // 中间的省略了 大家可以回去看 es6 Promise 学习笔记1
    ...
     
    function invokeCallback(settled, promise, callback, detail) {
      let hasCallback = isFunction(callback),
          value, error, succeeded = true;
     
      if (hasCallback) {
        try {
    // 看这里 callback其实就是我们传给then,catch,或者finally的回调
    // 但这里又接了一个返回值, 这个是对应 then,catch,finally里,回调返回 的是一个 Promise 的情况
    // *** _这里就的value就是我们then里返回的Promise2_
          value = callback(detail);
        } catch (e) {
          succeeded = false;
          error = e;
        }
    // 这个promise是 child 也就是 then,catch,finally
        if (promise === value) {
          reject(promise, cannotReturnOwn());
          return;
        }
      } else {
        value = detail;
      }
    // 这个promise是 child 也就是 then,catch,finally
      if (promise._state !== PENDING) {
        // noop
      } else if (hasCallback && succeeded) {
    // 正常情况 走这里, 如果callback 调用失败 或者 callback 不是 函数走下面三个分支
    // *** 第一个参数是根 Promise 第二个参数 value 是then 返回的Promise2
        resolve(promise, value);
      } else if (succeeded === false) {
        reject(promise, error);
      } else if (settled === FULFILLED) {
        fulfill(promise, value);
      } else if (settled === REJECTED) {
        reject(promise, value);
      }
    }
    

    Promise2的 创建

    // 这里的value 就是 then 返回的Promise2
    function resolve(promise, value) {
      if (promise === value) {
        reject(promise, selfFulfillment());
      } else if (objectOrFunction(value)) {
    // resolvePromise 传入的参数是一个 对象或者的函数的话
    // 这里判断了一下 他是否有 then 函数, 也就是说 resovle 的参数可以是 另一个Promise
        let then;
        try {
          then = value.then; // 这种value是 Promise 的情况后面我们会讲到
        } catch (error) {
          reject(promise, error);
          return;
        }
        handleMaybeThenable(promise, value, then);
      } else {
        fulfill(promise, value);
      }
    }
     
    import originalThen from './then';
    import originalResolve from './promise/resolve';
    function handleMaybeThenable(promise, maybeThenable, then) {
    // 判断传进来的是不是 一个Promise 构造函数相同,then相同,resolve也相同
    // maybeThenable 就是前面的 then 返回的Promise 就是 resolve的value
      if (maybeThenable.constructor === promise.constructor &&
          then === originalThen &&
          maybeThenable.constructor.resolve === originalResolve) {
        handleOwnThenable(promise, maybeThenable);
      } else {
        ...
      }
    }
    
    function handleOwnThenable(promise, thenable) {
      if (thenable._state === FULFILLED) {
        fulfill(promise, thenable._result);
      } else if (thenable._state === REJECTED) {
        reject(promise, thenable._result);
      } else {
    // 因为then里的 Promise2 是new 的所以 他的 _state是 undefined
    // 所以走这里
        subscribe(thenable, undefined, value  => resolve(promise, value),
                                       reason => reject(promise, reason))
      }
    }
    
    function subscribe(parent, child, onFulfillment, onRejection) {
      let { _subscribers } = parent;
      let { length } = _subscribers; // parent 是 new的 所以这里length === 0
    
      parent._onerror = null;
    
    // Promise2的_subscribers有3个值[undefined, promiseResolve, promiseReject]
      _subscribers[length] = child;
      _subscribers[length + FULFILLED] = onFulfillment;
      _subscribers[length + REJECTED]  = onRejection;
    
    // 因为 Promise2的_state是undefined的所以这个不会马上执行
    // 至此 Promise2创建完毕
      if (length === 0 && parent._state) {
        asap(publish, parent);
      }
    }
    
    

    Promise2的执行

    还是先回顾一下 es6 Promise 学习笔记1

    function publish(promise) {
      var subscribers = promise._subscribers;
      var settled = promise._state; // 这个state, resolve:1,reject:2.刚好根订阅者列表 里的参数列表顺序对应
     
      if (subscribers.length === 0) {
        return;
      }
     
      var child = void 0,
          callback = void 0,
          detail = promise._result;
    // Promise2的订阅者列表 [undefined, promiseResolve, promiseReject]
      for (var i = 0; i < subscribers.length; i += 3) {
        child = subscribers[i];
        callback = subscribers[i + settled]; // 根据当前Promise的状态走 不同的回调
     // child 是undefined
        if (child) {
          invokeCallback(settled, child, callback, detail);
        } else {
    // 直接调用callback,  value  => resolve(promise, value) 或者 reason => reject(promise, reason) 
    // 请注意这里的 promise 是根Promise 回到了 根的调用链上
          callback(detail);
        }
      }
     
      promise._subscribers.length = 0;
    }
    
    

    总结

    创建了:

    • 1个父Promise,
    • 4个子Promise,
    • 1个父Promise的订阅者列表, 这个列表的内容就是 4个子Promise 和 他们的 参数列表
      [then1,thenResolve1,thenReject1, then2,thenResolve2,thenReject2, catch,catchResolve,catchReject,finally,finallyResolve,finallyReject]
    • thenResolve1执行完了后,返回一个Promise2 创建它的订阅者列表 [undefined, promise2Resolve, promise2Reject]
    • 执行thenResolve2 并将结果放到父Promise 的_result上 继续往下走

    es6 Promise 学习笔记1 基础代码解析
    es6 Promise 学习笔记2 链式调用
    es6 Promise 学习笔记3 Promise.all
    es6 Promise 学习笔记4 Promise.race

    相关文章

      网友评论

        本文标题:es6 Promise 学习笔记2 链式调用

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