Promise的一点疑惑?

var p = new Promise((resolve, reject) => { //这里的参数若是thenable的,规范有提到加入job队列,…
关注者
28
被浏览
7,890

11 个回答

无论 resolve 的参数是不是 thenable,Promise 构造函数接收的参数 executor,都是同步执行的。

V8 版本 8.4,Promise 构造函数源码如下

PromiseConstructor(
    js-implicit context: NativeContext, receiver: JSAny,
    newTarget: JSAny)(executor: JSAny): JSAny {
  const promiseFun = UnsafeCast<JSFunction>(
      context[NativeContextSlot::PROMISE_FUNCTION_INDEX]);
  let result: JSPromise;
  result = NewJSPromise();

  const funcs = CreatePromiseResolvingFunctions(result, True, context);
  const resolve = funcs.resolve; // executor 第一个参数:resolve
  const reject = funcs.reject; // executor 第二个参数:reject
  try {
    // 在这一行同步调用了 executor
    Call(context, UnsafeCast<Callable>(executor), Undefined, resolve, reject);
  } catch (e) {
    Call(context, reject, Undefined, e);
  }
  return result;
}

从源码看 resolve 的参数是 thenable 时,有加入 microtask 队列的操作,但那是 resolve 函数的逻辑,与 executor 没有关系。

本题中 resolve 接收的参数不是 thenable 对象,自然没有加入 microtask 队列的操作,一切都是同步执行。从源码看 resolve 执行一半的时候,p 就已经是 fulfilled 状态了。

泻药

没看懂你说啥……

这个例子是同步的啊

fulfilled 了

大概你是要问这个吧……

25.4.1.3.2Promise Resolve Functions#

A promise resolve function is an anonymous built-in function that has [[Promise]] and [[AlreadyResolved]] internal slots.

When a promise resolve function F is called with argument resolution, the following steps are taken:

  1. Assert: F has a [[Promise]] internal slot whose value is an Object.
  2. Let promise be the value of F's [[Promise]] internal slot.
  3. Let alreadyResolved be the value of F's [[AlreadyResolved]] internal slot.
  4. If alreadyResolved.[[Value]] is true, return undefined.
  5. Set alreadyResolved.[[Value]] to true.
  6. If SameValue(resolution, promise) is true, then
    1. Let selfResolutionError be a newly created TypeError object.
    2. Return RejectPromise(promise, selfResolutionError).
  7. If Type(resolution) is not Object, then
    1. Return FulfillPromise(promise, resolution).
  8. Let then be Get(resolution, "then").
  9. If then is an abrupt completion, then
    1. Return RejectPromise(promise, then.[[Value]]).
  10. Let thenAction be then.[[Value]].
  11. If IsCallable(thenAction) is false, then
    1. Return FulfillPromise(promise, resolution).
  12. Perform EnqueueJob("PromiseJobs", PromiseResolveThenableJob, « promise, resolution, thenAction »).
  13. Return undefined.

The length property of a promise resolve function is 1.

25.4.1.4FulfillPromise ( promise, value)#

When the FulfillPromise abstract operation is called with arguments promise and value, the following steps are taken:

  1. Assert: the value of promise's [[PromiseState]] internal slot is "pending".
  2. Let reactions be the value of promise's [[PromiseFulfillReactions]] internal slot.
  3. Set the value of promise's [[PromiseResult]] internal slot to value.
  4. Set the value of promise's [[PromiseFulfillReactions]] internal slot to undefined.
  5. Set the value of promise's [[PromiseRejectReactions]] internal slot to undefined.
  6. Set the value of promise's [[PromiseState]] internal slot to "fulfilled".
  7. Return TriggerPromiseReactions(reactions, value).