Async Programming

Asynchronous programming

Synchronous programming: barring conditionals and function calls, code is executed sequentially from top-to-bottom, blocking on long-running tasks (network requests, disk I/O, ...).

Asynchronous programming: the engine runs in an event loop. When a blocking operation is needed, the request is started, and the code keeps running without blocking for the result. When the response is ready, an interrupt is fired, which causes an event handler to be run, where the control flow continues. In this way, a single program thread can handle many concurrent operations.

User interfaces are asynchronous by nature, and spend most of their time waiting for user input to interrupt the event loop and trigger event handlers.

Node is asynchronous by default: the server works in much the same way, waiting in a loop for a network request, and accepting more incoming requests while the first one is being handled.

This is important in JavaScript, because it is a very natural fit for user interface code, and very beneficial to performance on the server.

Synchronous functions are blocking while asynchronous functions are not. In synchronous functions, statements complete before the next statement is run.

Event loop

Single-threaded loop that monitors the call stack and checks if there is any work to be done in the task queue.

If the call stack is empty and there are callback functions in the task queue, a function is dequeued and pushed onto the call stack to be executed.

Example

What is the result of the following code?

function printing() {
   console.log(1); 
   setTimeout(function() { console.log(2); }, 1000); 
   setTimeout(function() { console.log(3); }, 0); 
   console.log(4);
}

printing();

Answer

1 // first statement
4 // first non-delayed statement
3 // queued but with 0 delay
2 // queued with delay

When calling the setTimeout() function the callback provided is queued, even if the delay specified is zero. The callback stays in the queue until the time specified has elapsed and the engine is ready to perform the action (i.e. if it isn’t performing another action at the moment).

So, although a callback passed to setTimeout() is delayed by zero milliseconds, it’ll be queued and executed after other non-delayed statements declared in the same function.

Promises

Object that may produce a single value some time in the future: either a resolved value, or a reason that it’s not resolved (e.g., a network error occurred)

Object which can be returned synchronously from an asynchronous function.

Possible states:

  • Fulfilled: onFulfilled() will be called (e.g., resolve() was called)

  • Rejected: onRejected() will be called (e.g., reject() was called)

  • Pending: not yet fulfilled or rejected

JS promises don’t expose promise states. Instead, you’re expected to treat the promise as a black box. Only the function responsible for creating the promise will have knowledge of the promise status, or access to resolve or reject.

Every promise must supply a .then() method

Promise Chaining

Because .then() always returns a new promise, it’s possible to chain promises with precise control over how and where errors are handled.

Like synchronous code, chaining will result in a sequence that runs in serial. Example:

fetch(url)
  .then(process)
  .then(save)
  .catch(handleErrors)
;

Promises vs Callbacks

Pros

  • Avoid callback hell which can be unreadable.

  • Makes it easy to write sequential asynchronous code that is readable with .then().

  • Makes it easy to write parallel asynchronous code with Promise.all().

  • These scenarios which are present in callbacks-only coding, will not happen:

    • Call the callback too early

    • Call the callback too late (or never)

    • Call the callback too few or too many times

    • Fail to pass along any necessary environment/parameters

    • Swallow any errors/exceptions that may happen

Cons

  • Slightly more complex code (debatable).

  • In older browsers where ES2015 is not supported, you need to load a polyfill in order to use it.

References

Last updated