What is hard to understand is that resolve
doesn't work the same way as return
. Creating Promises
actually creates a new async context. Everything inside the first function of the Promise
is executed synchronously. Then the .then()
methods are called with the values resolved synchronously or asynchronously.
In the first example, you resolve '1'
, but then you create a new Promise
with Promise.resolve()
and you call the .then()
right away. Because the new Promise
is inside the first one, everything is called synchronously.
new Promise(resolve => {
resolve('1'); // Will be accessed in the .then() after then end of the callback
Promise.resolve().then(() => log('2')); // called before the end of the function
// because the context is not yet created
}).then(data => {
log(data);
}); // output 2 1
The second example is way harder. You actually create a Promise
inside the first Promise
and call its resolve
right away. The order of execution will be:
- first everything in the initial callbacks
- After that, create sort of
eventListeners
from the resolve
to the .then
- When a
resolve
is called, execute the callback in .then
There is nothing in the initial function of the nested promise
. So it goes straight to the then
. The .then()
calls the initial resolve()
. Here, the kind of eventListener
is created so we jump to the initial callback. Then we go back and execute the rest of the function.
new Promise(resolve => {
// Because we call resolve right away, the context of the original promise
// is created
Promise.resolve().then(() => {
resolve('1'); // Calling resolve jumps us to the .then
Promise.resolve().then(() => log('2')); // We execute after.then
});
}).then(data => {
log(data);
}); // output 1 2
If you removed the .resolve()
, it would work like the first one:
new Promise(resolve => {
new Promise(() => {
resolve('1');
Promise.resolve().then(() => log('2'));
});
}).then(data => {
log(data);
}); // output 2 1