每天一道 JS 高级编程训练题——颠覆你认知的 Promise 执行顺序

81 阅读1分钟

引言

这里是 JS 高级编程训练集,用于练习巩固 JS 使用能力,随更

往期收录

颠覆你认知的 Promise 执行顺序

Promise.resolve()
    .then(() => {
      console.log(0)
      return Promise.resolve(4)
    })
    .then(res => {
      console.log(res)
    })

Promise.resolve()
    .then(() => {
      console.log(1)
    })
    .then(() => {
      console.log(2)
    })
    .then(() => {
      console.log(3)
    })
    .then(() => {
      console.log(5)
    })
    .then(() => {
      console.log(6)
    })
// 在 v8 引擎中输出的值?

解析:

  • 根据 Promises/A+规范,在处理Promise Resolve结果时,如果返回的也是一个 Promise,则吸收其状态;其吸收状态后具体的处理逻辑(队列排序、执行时机)依据各执行平台的具体机制进行处理
  • 在 V8 引擎里,对于处理 Promise Resolve 返回一个 Promise 这种情况,它的做法是返回一个全新的 Promise,即产生一个全新的微任务进行加入微队列
PromisePrototypeThen(js-implicit context: NativeContext, receiver: JSAny)(
    onFulfilled: JSAny, onRejected: JSAny): JSAny {
  const promise = Cast<JSPromise>(receiver) otherwise ThrowTypeError(
      MessageTemplate::kIncompatibleMethodReceiver, 'Promise.prototype.then',
      receiver);
 
  const promiseFun = UnsafeCast<JSFunction>(
      context[NativeContextSlot::PROMISE_FUNCTION_INDEX]);
 
  let resultPromiseOrCapability: JSPromise|PromiseCapability;
  let resultPromise: JSAny;
  label AllocateAndInit {
    // 创建一个新的 promise 用于当做本次 then 的调用结果返回
    //(上面有提到then的返回值是一个promise)
    const resultJSPromise = NewJSPromise(promise);
    resultPromiseOrCapability = resultJSPromise;
    resultPromise = resultJSPromise;
  }
  // onFulfilled 和 onRejected 是 then 接收的两个参数
  // 如果不传则默认值为 Undefined
  const onFulfilled = CastOrDefault<Callable>(onFulfilled, Undefined);
  const onRejected = CastOrDefault<Callable>(onRejected, Undefined);
 
  // 调用 PerformPromiseThenImpl 函数
  PerformPromiseThenImpl(
      promise, onFulfilled, onRejected, resultPromiseOrCapability);
  // 返回一个新的 Promise
  return resultPromise;
}
  • 每个 then 里产生的微任务需要等待上个 then 对应的状态为 fulfilled 后再生成。