JavaScript Async/Await Tricks

The sweetest syntactic sugar of all, with magic.

In Immediately Invoked Function Expression (IIFE)

  • the classic way
(async () => {
  // code goes here
})();

In process.nextTick, in Node.js

  • somewhat similar to IIFE, but specific to Node.js
  • somewhat similar to top-level async-await, just one tick away
process.nextTick(async () => {
  await some_function();
});

In setTimeout

  • when you don't feel like using IIFE
  • because there is no setImmediate and process.nextTick in browsers
setTimeout(async () => {
  // code goes here
}, 1);

In for-loops

  • execute asynchronous functions in series, one at a time
  • will throw when one item fails
process.nextTick(async () => {

  const example_async_function = async (item) => {
    console.log({ item });
    await new Promise((resolve) => setTimeout(resolve, 1000));
  };

  const items = [1, 2, 3];
  for (let i = 0, l = items.length; i < l; i += 1) {
    const item = items[i];
    await example_async_function(item);
  }

});

In Array Maps

  • execute asynchronous functions in parallel, all at once
  • will throw when one item fails

process.nextTick(async () => {

  const example_async_function = async (item) => {
    console.log({ item });
    await new Promise((resolve) => setTimeout(resolve, 1000));
  };

  const items = [1, 2, 3];
  await Promise.all(items.map(async (item) => {
    await example_async_function(item);
  }));

});

For non-blocking sleep

  • when you feel like waiting a few seconds or milliseconds, useful for tests
process.nextTick(async () => {
  await new Promise((resolve) => setTimeout(resolve, 1000));
});

For non-blocking waiting of events

  • when you feel like waiting for events, useful for tests
// CommonJS Modules
const { EventEmitter } = require('events');

// ECMAScript Modules
import { EventEmitter } from 'events';

process.nextTick(async () => {
  const emitter = new EventEmitter();
  console.log('emitter created');

  setTimeout(() => emitter.emit('event_name'), 1000);

  await new Promise((resolve) => emitter.once('event_name', resolve));
  console.log('emitter emitted event_name');
});
// CommonJS Modules
const fs = require('fs');

// ECMAScript Modules
import fs from 'fs';

process.nextTick(async () => {

  const stream = fs.readFileSync(file_path);
  console.log('stream started.');

  await new Promise((resolve) => stream.on('end', resolve));
  console.log('stream ended.');

});