Reputation: 1016
I have problem understanding how async function work in JavaScript. Let's take the code below:
async () => {
console.log(1);
setTimeout(() => console.log(2)
, 2000)
console.log(3);
}
I would expect that invocation of synchronous function inside async should block thread before executing further code. So I'd expect to get 1 -> 2 -> 3
instead I'm getting 1 -> 3 -> 2
. Can't find explanation why it's happening and how to block thread to receive output 1 -> 2 -> 3
.
I'm using Node 12 with serverless framework.
Upvotes: 1
Views: 328
Reputation: 15166
async
itself won't wait until execution of setTimeout
finished as you expect. As you can read from the documentation - find here for async
:
An async function can contain an await expression that pauses the execution of the async function to wait for the passed Promise's resolution, then resumes the
async
function's execution and evaluates as the resolved value.
Just built a quick example to see the difference between async
and await
solution and just using setTimeout
as it is in your example.
Consider the following example:
const getPromise = async () => {
return new Promise((resolve) => {
setTimeout(resolve, 3000);
});
}
const run = async () => {
console.log('run started');
setTimeout(() => console.log('setTimeout finised'), 2000);
console.log('setTimeout started');
const promise = await getPromise();
console.log('Promise resolved');
console.log('run finished');
}
run();
Steps explained:
run
execution startedsetTimeout
which will be finished in ~2 secondssetTimeout
startedgetPromise
function and with await
keyword wait till resolve
setTimeout
logs that it has been finishedPromise
the resolve
function calledrun
function finishes its execution after resolve
and logging.I hope that helps you understand this portion of the code.
Upvotes: 1
Reputation: 944456
I would expect that invocation of synchronous function inside async should block thread before executing further code.
It does
So I'd expect to get 1 -> 2 -> 3 instead I'm getting 1 -> 3 -> 2.
setTimeout
is not synchronous. It very explicitly is for queuing up a function to run later, after some time has passed.
Can't find explanation why it's happening and how to block thread to receive output 1 -> 2 -> 3.
You can't per se.
The closest you could come would be to replace setTimeout
with a loop that runs around in circles until some time has passed… but that would be awful (it would lock up the UI for starters).
If you want to just run the three logs in order, then replace setTimeout
with something that returns a promise and then await
it (which would put the async function to sleep and let any other code continue to run until the promise resolved).
const timeout = function() {
return new Promise(function(res) {
setTimeout(() => {
console.log(2);
res();
}, 2000)
})
};
const x = async() => {
console.log(1);
await timeout();
console.log(3);
}
x();
Upvotes: 1