美文网首页源码学习
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