the following code results into the expected output
function toppings_choice() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(console.log("which topping would you love?"));
reject("not working");
}, 3000);
});
}
async function kitchen() {
console.log("A");
console.log("B");
console.log("C");
await toppings_choice();
console.log("D");
console.log("E");
}
kitchen();
/* Stackoverflow: show only console */
.as-console-wrapper {
max-height: 100% !important;
top: 0;
}
output:
A
B
C
which topping would you love?
D
E
but for some reason await in the following syntax does not work
async function toppingChoice() {
setTimeout(() => {
if (true) {
return console.log("which topping would you love?");
} else {
throw "not working";
}
}, 3000);
}
async function kitchenTwo() {
console.log("A");
console.log("B");
console.log("C");
await toppingChoice();
console.log("D");
console.log("E");
}
kitchenTwo();
/* Stackoverflow: show only console */
.as-console-wrapper {
max-height: 100% !important;
top: 0;
}
output:
A
B
C
D
E
which topping would you love?
both functions return a promise, so why is the await keyword working in the first code and indeed stopped the code until the promise was resolved but did not work in the second code?
I need to know if I could use the syntactic sugar of sync/await without having to use the promise constructor
2
Answers
Not really, at least it’s not the case for your
toppingChoice
.The first one
returns a promise which is fulfilled only after the timeout calls its callback.
The second
doesn’t return anything in explicit way (no
return
) which makes it implicitely return a fulfilled promise withundefined
value. When this promise is awaited, it doesn’t even make the execution wait for anything. It’s only 3000,s later when the timeout callback is called.Note that adding
return
herewon’t help much as the result of
setTimeout
is not meant to be awaited (it’s the timer id, a number).You can, assuming you run your code in node. Node has two versions of the
setTimeout
, the old one, compatible with the browser API and an new one that returns a promise.The problem in your 2nd approach is, that you return a
Promise
(since all function with theasync
keyword do that), but that promise immediately resolves (or better: a completedPromise
is returned), therefore the program continues to run and exits before the callback specified forsetTimeout()
is scheduled to run on the event loop.If you were to wait longer than 3 seconds before exiting the program you could observe that the callback actually gets invoked:
To really understand how this works you need an understanding of the event loop in JavaScript and you need to understand that behind a Promise is actually a state machine but all of that is too much to go into detail here. Please have a look at the referenced resources.