2

As I understand a promise is something that can resolve() or reject(), and this action should be done after some work as completed, so it should be invoked as part of the callback like in this example:

let timeout = new Promise((resolve) => {
    console.log('function called');
    setTimeout(() => {
        console.log("timeout finisced!");
        resolve()
    }, 1000)
});

timeout.then(() => {
    console.log("timeout resolved!")
});

console.log('teminated!');

result

 function called
    teminated!
    timeout finisced!
    timeout resolved!

But the thing I can't understand is how they work when there isn't an asynchronous action to do and so, if you think synchronously, the resolve function should be called in the constructor of the promise, even if you don't have a handler for it and then the then() method should be able to handle it after; but from what I can see from this example, the code is executed in the same way. So can someone explain the thought behind why the following example works in this way?

new Promise(function(resolve) {
    console.log('function called')
    resolve();
}).then(() => {
    console.log('function resolved');
});

console.log('teminated!');

result:

function called
teminated!
function resolved

Edit:

I have mostly understanded what’s happening, the thing that now I am not sure is how this is done. So correct me if I’m wrong, the .then() method is always put in the micro task queue no matter what, so even if you pass it synchronous code, it is not executed in the stack directly like other synchronous code. And for that to happen the state of the promise should be fulfilled or rejected, and to do that the function resolve() or reject() should be called. So now I would like to understand the process that is behind it, like what does the then() method effectively do? You pass it a callback and that is stored in the promise object or what? And because the callback is put on the micro task queue after it is fulfilled or rejected, does that mean it is the resolve() function that puts it in the micro task queue? That should be a reasonable assumption based on this example below; or does the resolve function only change the state and then is the then() method that puts it in the queue?

const p = Promise.resolve();
p.then(() => console.log("callback 1"));
 
const p2 = Promise.resolve();
p2.then(() => console.log("other micro task"));
 
p.then(() => console.log("callback 2"));
 
/*
    result:
    callback 1
    other micro task
    callback 2
*/
 
 
const p = Promise.resolve();
p.then(() => console.log("callback 1"));
 
const p2 = new Promise((resolve) => {
    setTimeout(() => resolve(), 0)
});
p2.then(() => console.log("other micro task"));
 
p.then(() => console.log("callback 2"));
 
/*
    result:
    callback 1
    callback 2
    other micro task
*/

The only thing I’m sure of is that there are multiple callbacks for a single promise, they aren’t always executed one by one in order, but there can be another micro task before it like in the first example.


I'm aware that this may be a stupid problem, but for some reason it put's me in confusion, so thank's in advance for the help.

Colin
  • 61
  • 6
  • 1
    Mainly for consistency, so that `.then()` always works the same way no matter what the promise did. And you don't use promises anyway if you have only synchronous code. – Bergi Feb 20 '22 at 14:56
  • @Bergi Thanks, I found out before it wasn't like this, but for that reason they changed how it works. Now I edited the post based on what I still don’t fully understand, can you check to see if you understand or if what I wrote doesn’t make sense? – Colin Feb 21 '22 at 12:23
  • "*What does the then() method effectively do, store the passed callback in the promise object or what?*" - yes. "*Does that mean it is the resolve() function that puts it in the micro task queue?*" - yes. "*Or does the resolve function only change the state and then is the then() method that puts it in the queue?*" - `resolve` **also** changes the state of the promise, so that future `.then()` calls will put their callbacks right into the microtask queue when the promise is already fulfilled; in those cases it's `then` that does the scheduling. – Bergi Feb 21 '22 at 14:58
  • *"If there are multiple callbacks for a single promise, they aren’t always executed one by one in order*" - they are guaranteed to be in the same order in which their `.then()` calls were made, but yes, they might be interleaved with other microtasks (from other promises). – Bergi Feb 21 '22 at 14:59
  • @Bergi Thanks a lot, that cleared all the doubts that I had – Colin Feb 22 '22 at 08:15

1 Answers1

1

First, promises are async (then part), async/await is built on top of them. And the promise is not a simple async code, but a micro task, its executed after sync code, but before macro tasks (such as timeouts). So in your case we have sync promise part function called, than sync code teminated, than async part after promise resolved function resolved.

To better undestand how micro/micro tasks and event loop works, I recommend you to check out answers here: Difference between microtask and macrotask within an event loop context

Eugene Mihaylin
  • 1,736
  • 3
  • 16
  • 31