源码追踪
下面我来按照执行流程分步说明 PromiseResolveThenableJobTask 微任务是如何被创建、入队并执行的:
1. 触发点 --- PromiseResolve 发现 resolution 是 thenable
- 逻辑在 promise::ResolvePromise 中:当 resolution 不是原生 fulfilled 值且有可调用的 then 时,会进入 Enqueue 分支,创建任务并入队(见 Enqueue 段)。

2. 创建任务对象 NewPromiseResolveThenableJobTask
-
创建任务的宏定义在 promise::NewPromiseResolveThenableJobTask。该宏把 then 的执行上下文(thenContext 的 nativeContext)放入任务的 context 字段,并把 promise_to_resolve / thenable / then 存入任务。

-
任务类型与字段定义在对象描述里:v8::internal::PromiseResolveThenableJobTask(成员:context, promise_to_resolve, thenable, then)。

3. 入队(HostEnqueuePromiseJob / EnqueueMicrotask)
- 在 Torque 代码里使用 EnqueueMicrotask(task.context, task) 进入微任务队列,实际的入队 builtin 实现在 TF_BUILTIN(EnqueueMicrotask):把任务写入 native_context 对应的 MicrotaskQueue 的环形缓冲(或调回 C++ 扩容回调)。


4. 任务在微任务循环中被取出并分发执行
- 微任务循环由 TF_BUILTIN(RunMicrotasks) 实现:循环从 ring buffer 取出 microtask、更新 start/size,然后调用
RunSingleMicrotask(current_context, microtask)。
5. RunSingleMicrotask 中对 PromiseResolveThenableJobTask 的处理路径
-
在 MicrotaskQueueBuiltinsAssembler::RunSingleMicrotask 中有对微任务类型的 switch,其中有分支
is_promise_resolve_thenable_job。该分支:a. 进入任务记录的 context(PrepareForContext / EnterContext / SetCurrentContext)
b. 加载 task 的字段:
promise_to_resolve,thenable,then(从任务对象字段读出)c. (可选)SetupContinuationPreservedEmbedderData(构建器选项)
d. 调用 RunAllPromiseHooks(PromiseHookType::kBefore, microtask_context, promise_to_resolve)(在调用实现前触发 Promise hook)
e. 调用内建实现:
CallBuiltin(Builtin::kPromiseResolveThenableJob, native_context, promise_to_resolve, thenable, then)f. 调用 RunAllPromiseHooks(PromiseHookType::kAfter, microtask_context, promise_to_resolve)(after hook)并恢复上下文/清理。

6. PromiseResolveThenableJob 的真正语义(builtin 实现)
- builtin 的实现逻辑在 Torque 文件 src/builtins/promise-jobs.tq;
PromiseResolveThenableJob会按照规范对 thenable 调用 then(或直接把 thenable 链接到 promise_to_resolve):- 如果,then===原生promiseThen,直接调用 PerformPromiseThen(thenable, Undefined, Undefined, promise_to_resolve)->PerformPromiseThenImpl(即把 thenable 的结果转接到 promise_to_resolve),
- 否则,创建 resolving functions 并调用 then(并在异常时调用 reject)。
7. 相关的对象层次 & 其它点
- 在 C++ 层,JSPromise::Resolve 在某些路径会调用工厂创建并入队任务(见 JSPromise::Resolve 中创建
NewPromiseResolveThenableJobTask并把任务放到microtask_queue->EnqueueMicrotask(*task)的实现)。

- Promise hooks(before/after/resolve/init)由一系列 RunAllPromiseHooks 调用(在微任务执行前后调用),实现参见上面 RunAllPromiseHooks(都在 builtins-microtask-queue-gen.cc)。
总结(简短流程):
- PromiseResolve 发现 resolution 是 thenable -> 调用 NewPromiseResolveThenableJobTask 创建任务并设置 task.context=then 的 realm(promise-resolve.tq/promise-misc.tq)。
- 通过 EnqueueMicrotask(task.context, task) 将任务放入对应 native context 的 MicrotaskQueue(builtins-microtask-queue-gen.cc 的 EnqueueMicrotask)。
- RunMicrotasks 循环取出任务并调用 RunSingleMicrotask。
- 对于 PromiseResolveThenableJobTask 分支,先触发 before-hook,再执行 builtin
PromiseResolveThenableJob(在 promise-jobs.tq 中实现 then 调用 -- PerformPromiseThen 的语义),最后触发 after-hook 并恢复上下文。