A slight miss conception of promises, is that there async. But there really only just a contract, that is then placed into a queue that will get processed before the next event loop. Very useful for writing async code, much nicer than callbacks.
Below is a simple example with 2 promises, 1 promise is not doing anything async, the other is doing a simple async sleep. That async sleep is very important, because this allows the browser to process the next event loop. If you take this sleep out, and re-run, watch how the browser will hang.
Please NOTE: be prepared to use say Chrome's task manager to kill the
browser TAB when you comment out the await sleep(1)
.
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
async function nothingProm() {
// a promise that does no async stuff
}
//this infinate loop will not hang the browser
async function test() {
while (true) {
await nothingProm();
await sleep(1); //remove this for HANG!!!
}
}
test();
Now in the above it might seem strange why does removing that sleep cause the browser to hang.
Browsers use something called an event loop, this is responsible for getting things like mouse clicks, timers etc, and dispatching them to listeners. This is very similar to how cooperative multi-tasking OS's work, think Window 3.11.
So, inside the browser TAB there will be an Event Loop running, doing something like ->
while (running) {
var message = getNextMessage();
dispatchMessage(message);
}
That getNextMessage
above will efficiently wait for some event, timer, mouse move, etc etc. So it won't be wasting CPU resources, even thought it's in this tight LOOP.
So what does this have to do with promises you may ask. Well this bit is where the microtask
comes in, unlike macrotask
like a timer, that the browser can dispatch from, there basically stuck into a queue that get drained before the next macrotask
is processed.
while (running) {
var message = getNextMessage(); // (1)
dispatchMessage(message); // (2)
processMicroTaskQueue(); // (3)
}
So if you had promises that's only did stage (3), constantly the browser gets stuck at (3), as such does not get any chance to process any macrotasks
, IOW: The browser HANGS!!
Hopefully that makes sense, and I've used the correct terminology etc.
ps. Very similar to 3.11, a badly written app that never gave chance for the OS to process it's event loop, would in fact hang the whole OS. Strange how these things come round again.. :)