Yes, I know, the question title is a bit provocatory. But let me explain.
I needed to execute a sequence of async tasks in JavaScript. They are async because I need them to be non-blocking, but I still want the current task to end before starting the next one. The order of tasks doesn't matter, the only important thing is that they are in mutual exclusion with each other.
For this reason, maybe because of C/C++ background, I was about to implement a queue and a system of locks. Then I stop to think if the problem could be solved just using async/await, and I ended up with this solution:
previousPromise = null;
async function enqueue(task) {
while (previousPromise) {
await previousPromise;
}
previousPromise = executeTask(task);
await previousPromise;
previousPromise = null;
}
In practice, I use the promise subscribers internal queue as the lock queue, in order to achieve a non-blocking wait. When the promise resolves, it awakes all the async tasks† and the first finding previousPromise
equals to null will continue.
Here is a codepen example.
Is this solution solid? Thank you
Side note 1: a real lock system is obviously not needed. JavaScript is single-threaded, so there isn't any risk to be preempted after the while and before
executeTask
assignment.Side note 2: the tasks arrive from the server in an asynchronous fashion, so I can't collect them all before executing.
† It actually calls the first callback in the subscriber's list