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)
- 设完成为 Call(executor, undefined, «resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»).
- 如果完成是突然完成,那么
- 设状态为 Call(resolvingFunctions.[[Reject]], undefined, «completion.[[value]]»).
- ReturnIfAbrupt(状态)。
ES6 标准表明承诺的实现总是 异步(参见第 25.4.5.3 节,Promise.prototype.then
和随附的第 25.4.5.3.1 节,PerformPromiseThen
).我把相关的 material 放在了下面。
PerformPromiseThen
- 否则,如果 promise 的 [[PromiseState]] 内部插槽的值为 "fulfilled",
- 令 value 为 promise 的 [[PromiseResult]] 内部插槽的值。
- 执行 EnqueueJob("PromiseJobs", PromiseReactionJob, «fulfillReaction, value»).
- 否则,如果 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].
假设我有这个代码
function y(resolve, reject)
{
console.log("Result");
resolve();
}
var promise = new Promise(y);
我想知道函数y
会不会异步执行
这取决于承诺的执行情况。如果我们检查 the spec. You can find the final spec here - 因为这个答案最初是写的,所以它已经完成。
这里是相关的摘录(你可以找到原始出处here)
- 设完成为 Call(executor, undefined, «resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]»).
- 如果完成是突然完成,那么
- 设状态为 Call(resolvingFunctions.[[Reject]], undefined, «completion.[[value]]»).
- ReturnIfAbrupt(状态)。
ES6 标准表明承诺的实现总是 异步(参见第 25.4.5.3 节,Promise.prototype.then
和随附的第 25.4.5.3.1 节,PerformPromiseThen
).我把相关的 material 放在了下面。
PerformPromiseThen
- 否则,如果 promise 的 [[PromiseState]] 内部插槽的值为 "fulfilled",
- 令 value 为 promise 的 [[PromiseResult]] 内部插槽的值。
- 执行 EnqueueJob("PromiseJobs", PromiseReactionJob, «fulfillReaction, value»).
- 否则,如果 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
oronRejected
must not be called until the execution context stack contains only platform code. [3.1].