Promise构造函数回调是异步执行的吗?

Is the Promise constructor callback executed asynchronously?

假设我有这个代码

function y(resolve, reject)
{
  console.log("Result");
  resolve();
}  

var promise = new Promise(y);

我想知道函数y会不会异步执行

这取决于承诺的执行情况。如果我们检查 the spec. You can find the final spec here - 因为这个答案最初是写的,所以它已经完成。

这里是相关的摘录(你可以找到原始出处here

  1. 设完成为 Call(executor, undefined, «resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»).
  2. 如果完成是突然完成,那么
    • 设状态为 Call(resolvingFunctions.[[Reject]], undefined, «completion.[[value]]»).
    • ReturnIfAbrupt(状态)。

ES6 标准表明承诺的实现总是 异步(参见第 25.4.5.3 节,Promise.prototype.then 和随附的第 25.4.5.3.1 节,PerformPromiseThen).我把相关的 material 放在了下面。

PerformPromiseThen

  1. 否则,如果 promise 的 [[PromiseState]] 内部插槽的值为 "fulfilled",
    • 令 value 为 promise 的 [[PromiseResult]] 内部插槽的值。
    • 执行 EnqueueJob("PromiseJobs", PromiseReactionJob, «fulfillReaction, value»).
  2. 否则,如果 promise 的 [[PromiseState]] 内部插槽的值为 "rejected",
    • 让 reason 成为 promise 的 [[PromiseResult]] 内部插槽的值。
    • 执行 EnqueueJob("PromiseJobs",PromiseReactionJob,«rejectReaction,原因»)。

TLDR:传递给promise的函数是同步执行的,但是后续的then调用总是异步执行的。

另一个答案证明了这个,但是我来说说推理:

Promise 构造函数

promise 构造函数回调(在 ES6 规范或构造函数规范库实现中指定)将始终同步执行 - 这是为了从中提取延迟(旧形式的 promise 构造)以防万一您需要有权访问 resolve 回调:

var r;
var p new Promise(function(resolve, reject){
    r = resolve;
});
// use r here, for example
arr.push(r);

then 回调

then 将始终异步执行,几乎所有主流的 promise 实现(Native、bluebird、$q、Q、when、rsvp、promise、jQuery(自 3.0 起)等)如以及本机承诺实现(或实现具有更多约束的超集)Promises/A+

这正是 Promises/A+ 是由 Promises/A 创建的原因。将保留异步保证,并且不会发布 Zalgo。 (另见 this post)。

发生这种情况(异步保证)的事实完全是故意的并且主动防止竞争条件then 内外的代码将始终以相同的顺序执行。

相关引用如下:

onFulfilled or onRejected must not be called until the execution context stack contains only platform code. [3.1].