17

假设我有这个代码

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

var promise = new Promise(y);

我想知道的是函数是否y会异步执行。

4

2 回答 2

15

这取决于承诺的执行情况。如果我们检查规范您可以在此处找到最终规范- 由于此答案最初是编写的,因此已最终确定。

这是相关摘录(您可以在此处找到原始来源)

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

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

执行承诺然后

  1. 否则,如果 Promise 的 [[PromiseState]] 内部槽的值是“满足”的,
    • 令 value 为 promise 的 [[PromiseResult]] 内部槽的值。
    • 执行 EnqueueJob("PromiseJobs", PromiseReactionJob, «fulfillReaction, value»)。
  2. 否则,如果 promise 的 [[PromiseState]] 内部 slot 的值是“rejected”,
    • 让 reason 是 promise 的 [[PromiseResult]] 内部槽的值。
    • 执行 EnqueueJob("PromiseJobs", PromiseReactionJob, «rejectReaction, reason»)。

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

于 2015-04-30T08:55:58.817 回答
8

另一个答案证明了这一点,但让我谈谈推理:

承诺构造函数

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)等)以及原生 Promise 实现(或实现一个超集,还有更多约束)承诺/A+

正是Promises/A+ 是由 Promises/A 创建的原因。异步保证将被保留,Zalgo 不会被释放。(另见这篇文章)。

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

这是相关的报价:

onFulfilled或者onRejected在执行上下文堆栈仅包含平台代码之前不得调用。[3.1]。

于 2015-04-30T09:55:23.897 回答