If I have the following code
const sleep = (ms) => new Promise((resolve) => {
setTimeout(resolve, ms);
});
// myFunction is some kind of network operation, a database fetch etc.
const myFunction = async (label) => {
console.log("enter " + label);
await sleep(500);
console.log("leave " + label);
return "return " + label;
}
// somewhere in the code, in some event handler
var varA = myFunction("a");
// ... do something with varA
// somewhere ELSE in the code, in some event handler
var varB = myFunction("b");
// ... do something with varB
The logging output will almost certainly be
enter a
enter b
leave a
leave b
So the second function call will be executed before the first finishes. I think I do understand why. await
is only syntactic sugar and not actually blocking.
Question
How can I guarantee that the nth call to myFunction
is being executed completely before the (n+1)th call starts? The logging output should be
enter a
leave a
enter b
leave b
- Is there a pattern?
- Is there any library I could use? (this node package seems to be unmaintained.)
Note: The function myFunction
might be a library function I cannot change.
Why await myFunction
does not work
The calls to myFunction
could be anywhere else, e.g. in a click event handler, so we cannot just await myFunction
. Which ever call enters first, should also leave the function body first (FIFO). As per this note, this is also NOT A DUPLICATE OF How can I use async/await at the top level?
If you use myFunction
inside a click handler like this
<button onClick="() => { var varA = myFunction('button a'); console.log(varA) }">hit me</button>
you cannot simply await myFunction
because if the user clicks several times myFunction
will be called several times before the first call returns.