You are viewing the preview version of this book
Click here for the full version.

Convert between Promises and callbacks

While Promises and async/await are increasingly the primary way to write asynchronous code in JavaScript, callbacks are still used in many places. Several libraries that adopted that style are slow to migrate to the more modern alternative, and browser (and Node) APIs are also slow to change.

For example, marked, a markdown compiler needs a callback when it's used in asynchronous mode:

marked(text, options, (err, result) => {
  // result is the compiled markdown
});

Similarly, setTimeout invokes a function when the time is up:

setTimeout(callback, 100);

Not to mention a ton of web APIs, such as Indexed DB, FileReader, and others. Callbacks are still everywhere, and it's a good practice to convert them to Promises especially if your code is already using async/await.

Callback styles

Callbacks implement the continuation-passing style programming where a function instead of returning a value calls a continuation, in this case, an argument function. It is especially prevalent in JavaScript as it does not support synchronous waiting. Everything that involves some future events, such as network calls, an asynchronous API, or a simple timeout is only possible by using a callback mechanism.

There are several ways callbacks can work. For example, setTimeout uses a callback-first pattern:

setTimeout(callback, ms);

Or functions can get multiple functions and call them when appropriate:

const checkAdmin = (id, isAdmin, notAdmin) => {
  if (/* admin logic */) {
    isAdmin();
  }else {
    notAdmin();
  }
};

How the callback is invoked can also vary. For example, it might get multiple arguments:

const getUserData = (id, cb) => {
  const user = /* get user */
  cb(user.id, user.profile, user.avatar);
};

Also, asynchronicity might be implemented as an object that emits events:

const reader = new FileReader();
reader.onload = (event) => {
  // event.target.result
}
reader.onerror = (error) => {
  // handle error
};
reader.readAsDataURL(blob);

Node-style callbacks

There is more, but you've reached the end of this preview
Read this and all other chapters in full and get lifetime access to:
  • all future updates
  • full web-based access
  • PDF and Epub versions