为什么同步使用 Promise return 会产生异步结果?

Why does synchronous use of a Promise return asynchronous results?

代码

我实际上认为新的 Ecmascript 6 Promise 实现在其内部工作中是同步的(在简化异步操作方面很有用)。然后我做了这个例子,我认为它是同步代码:

for (var i=0; i<5; i++) {

    foo = new Promise (function(resolve, reject) {

        console.log(i);
        resolve(i);
    });

    foo.then (function(i) {

        console.log(i);
    });
}

令我惊讶的是 returns:

0
1
2
3
4
0
1
2
3
4

我希望同步代码为 return:

0
0
1
1
2
2
3
3
4
4

问题

上面代码return的结果是什么解释?

当您调用 Promise 构造函数时,它将同步调用您提供给它的函数,这可能包括也可能不包括对其 resolvereject 的同步调用。不管它是否是 resolved/rejected,返回的 Promise 都有一个 then method ,您将其传递给另一个函数,并且再次 then 中的代码(注意,不是您的回调)同步执行,我们到达第 7 步:

Return PerformPromiseThen(promise, onFulfilled, onRejected, resultCapability).

PerformPromiseThen has a number of steps, but both step 8b and 9b result in a call to EnqueueJob 取决于它是否是 resolved/rejected,其中表示:

Add pending at the back of the Job Queue named by queueName.

(在此实例中的队列名称为 "PromiseJobs")

然后我们可以进一步按照规范查看 PromiseJobs 队列上的作业是如何被调用的,但最终它们不会出列和执行,而任何其他代码是 运行 - 即 for循环将 运行 在调用任何 then 回调之前完成。