I think the key understandings are
- a
new Promise
callback is always invoked synchronously (during the call)
- a
then
callback is always invoked asynchronously (later)
So the individual synchronous steps here are, in order:
new Promise(resolve => { // begins creating a promise
resolve(1); // fulfills the promise
Promise.resolve() // creates a promise
.then(…); // registers a callback
console.log(4); // logs the first line
}) // finishes the promise creation
.then(…); // registers a callback
console.log(3); // logs the second line
When the callbacks are registered, then
checks whether the promise is already settled, and this is the case here (for both promises), it immediately schedules them by putting them on a queue. In theory this queue defines a specific order, in practice you should ignore that (i.e. things scheduled at the same time can happen in any order). If you want a specific order, always make an explicit promise chain instead of relying on internal queuing.
So here we have two scheduled items:
() => // the first item is called with undefined (result of `Promise.resolve()`)
console.log(2) // logs the third line
t => // the second item is called with 1 (from the `resolve(1)` call)
console.log(t) // logs the fourth line