DEV Community

Navneet Karnani
Navneet Karnani

Posted on • Originally published at blog.mandraketech.in on

Understanding `async/await` in NodeJS/Typescript

Here is a Typescript example of evaluating, and understanding the behaviour of async/await in NodeJS.

This example, triggers multiple async calls, without waiting ( testAwait ). testAwait in turn, awaits sayHello to execute. There is some additional complexity to mimic of sayHello going one level deeper, and waiting for a timeout, for "even" triggers.

This example demonstrates the fact that an async will push the execution of the Promise into the queue at the end. So, next "scheduled" task will be executed first. Look for the sequence of 1-1-1 and figure things out for yourself.

// example 1
const logs: Array<string> = [];

// example 2
/* const logs = {
   push: console.log
} */

const TASK_COUNTER = 2 as const;
const GROUP_COUNTER = 2 as const;

function getOutputTimestamp(): string {
  return '';
  // return `${(new Date().toISOString)}: `;
}

async function sleep() {
  await setTimeout(() => {}, 1000);
}

function add(a: number, b: number) {
  return a+b
}

async function sayHello(prefix: number[], deeper: boolean ) {
  logs.push(`${getOutputTimestamp()}${prefix}: start - ${deeper? 'deep' : 'shallow'}`);
  if (deeper) {
    logs.push(`${getOutputTimestamp()}${prefix}: Deeper`)
    await sleep()
  }
  logs.push(`${getOutputTimestamp()}${prefix}: end - ${deeper? 'deep' : 'shallow'}`);
}

async function testAwait(prefix: number[]) {
  for (let i=1; i<=TASK_COUNTER; i++) {
    logs.push(`${getOutputTimestamp()}${prefix}: before ${prefix}-${i}`);
    await sayHello([...prefix, i], prefix.reduce(add,0) % 2 === 0);
    logs.push(`${getOutputTimestamp()}${prefix}: after ${prefix}-${i}`);
  }
}

async function run() {
  const promises = [];  
  for (let i=1; i<=GROUP_COUNTER; i++) {
    for(let j=1; j<=i; j++) {
      const counter = j;
      const msgPrefix = [i, counter]
      logs.push(`${getOutputTimestamp()}${msgPrefix}: trigger`);
      promises.push(testAwait(msgPrefix));
      logs.push(`${getOutputTimestamp()}${msgPrefix}: done`);
    }
  }
  return Promise.all(promises);
}

run().then(() => console.log(JSON.stringify(logs, undefined, 2)));

Enter fullscreen mode Exit fullscreen mode

Top comments (0)