rabbitco
rabbitco

Reputation: 2850

Why does synchronous use of a Promise return asynchronous results?

The code

I actually thought that the new Ecmascript 6 Promise implementation was synchronous in its inner workings (with good use for simplifying asynchronous operations). I then made this example, which I perceive as synchronous code:

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);
    });
}

and to my surprise it returns:

0
1
2
3
4
0
1
2
3
4

I would have expected synchronous code to return:

0
0
1
1
2
2
3
3
4
4

Question

What is the explanation for the result returned by the above code?

Upvotes: 0

Views: 122

Answers (1)

James Thorpe
James Thorpe

Reputation: 32202

When you call the Promise constructor, it will synchronously invoke the function you gave to it, which may or may not include a synchronous call to its resolve or reject. Regardless of whether it has been resolved/rejected, the returned Promise has a then method which you pass another function to, and again the code within then (note, not your callback) is executed synchronously, where we arrive at step 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 depending on whether it was resolved/rejected, where this says:

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

(queueName in this instance being "PromiseJobs")

We can then follow the spec further to see how the jobs on the PromiseJobs queue are invoked, but ultimately they are not dequeued and executed while any other code is running - ie the for loop will run to completion before any then callbacks are invoked.

Upvotes: 1

Related Questions