Table of contents:

Introduction

An overview:

  • promisify

  • Callback functions

  • Use async [function definition] and await [function call].

  • Find and us a synchronous version of the asynchronous function for which you are having to use the callback API or async/await.

  • Redesign and refactor your code so that, for example, your use of async/await is at a shallower level in the function call chain.

Promisify

See my other article on promisity -- Promisify.

Callback functions

A common reason for trying to avoid the use of callbacks is sometimes referred to as "callback hell". It's where one callback function is defined inside the definition of another callback function which in turn is defined in the definition of yet another surrounding callback function and so on.

In some cases you can alleviate that problem by defining a callback function "out-of-line". That might mean defining a function at top level (with the function keyword) and then using in the call to your asynchronous function.

async and await

Notes on await and async:

  • If you want to make a function call to an asynchronous function into a call that blocks, use await.

  • An async function returns a promise. Use await to wait for and resolve that promise, that is, to get the resolved value of that promise.

  • You can use await only inside a function defined with async or at top level.

  • Define an asynchronous function (that is, a function that returns a promise) by using the async keyword. Examples:

    async function f1(x) { return x * 3; } const f2 = async function(y) { return y * 4; } const f3 = (async (z) => { return z * 5; });

  • In order to call an asynchronous function and obtain its value (that is, the value of its resolved promise), use await. Examples:

    const result1 = await f1(3); console.log('result1:', result1); const result2 = await f2(4); console.log('result2:', result2); const result3 = await f3(4); console.log('result3:', result3);

  • A promise is "then-able". So, if you'd rather use a callback, you could do this:

    f1(6).then((w) => { console.log('w:', w); })

Use a synchronous function

If what you really want is a function that blocks, that is a synchronous function instead of an asynchronous one, you might be able to find one. You can look in the usual places, for example:

Redesign and refactor

When adapting to the above, you might want to redesign or refactor your code, for example, either in order to avoid "callback hell" (callbacks nested inside callbacks nested inside ...) or in order to reduce the need for a long chain of nested async functions (an async function that awaits on an async function that awaits ...).

When doing so, keep in mind:

  • With respect to callbacks, code in the body of the callback will usually execute after any mainline code. So, the mainline code must not depend on the callback code. So in this example:

    someAsyncFunc(arg1, ((x) => { // callback code })); // mainline code

The mainline code will typically run before the callback code.

And, you may want to define some callback functions "out of line" and at top level.

  • With respect to the use of async and await, you may want to raise the use of those function to as high a level in you code as possible.

Published

Category

Nodejs

Tags

Contact