We understand the call stack: call a function, it's pushed onto the stack, when it returns, it's popped off. But what about asynchronous code?
Enter the task queue.
The task queue (also known as the "message queue") is where asynchronous tasks are queued up to be processed. It's just a standard queue of things for our JS engine to do, nothing to be scared of. But remember: JS is non-blocking, so the tasks in the queue can't be handled immediately.
The rule of the task queue is simple: when the call stack is empty, the event loop (managed by the JS runtime) checks the task queue. If there are tasks in the queue, it pushes the first one onto the call stack to be executed. Take a look at this example again:
function startJob() {
setTimeout(() => {
console.log("Hi I'm async!");
}, 0);
console.log("Job started");
workOnJob();
}
function workOnJob() {
console.log("Working on job");
finishJob();
}
function finishJob() {
console.log("Job finished");
}
startJob();
Because the setTimeout says "run this 0 milliseconds from now", you might expect its callback to run instantly and produce this output:
Hi I'm async!
Job started
Working on job
Job finished
But this is what actually happens:
Job started
Working on job
Job finished
Hi I'm async!
Because the callback:
() => {
console.log("Hi I'm async!");
};
Was pushed into the task queue to be executed after the call stack is empty, and it's not empty until the final nested function finishJob returns.
There's a bug in Textio's analytics system. An engineer tried creating a deferred log using setTimeout. However, it always logs "success", even on failure!
Fix the bug so the setTimeout is used in the correct place! A helpful senior engineer seems to have whispered "scoping issue" walking by.
The finalizeJob function runs immediately, capturing the initial success value. finalizeJob should be the last function that runs!
The expected output is:
Processing messages: 42
Doing more stuff...
Processed 42 successfully!
---
Processing messages: -1
invalid data: how do we have negative messages??
Failed to process messages!
---
Processing messages: 9001
invalid data: way too many messages
Failed to process messages!
Consider the order in which your code executes: the setTimeout callback might be running before your validation checks update the success flag.