Node.js 16: setTimeout with async/await

On April 20, 2021 the Node.js was release with a new version — 16. It included a couple of notable changes like:

  • Engine update: V8 upgraded to V8 9.0
  • npm 7 default version
  • Toolchain and Compiler Upgrades
  • Stable AbortController implementation based on the
  • Stable Timers Promises API

The whole list can be viewed in the official .

As for now, version 16 will remain in Current release status for six months. It means it’s already usable, can be installed on your environment, but still not recommended for production. The authors have time to add support for all its features and after six months it will be moved to Active LTS status. Only then it’ll be treated as the newest for production usage.

setTimeout — old way:

Among all the listed features, Stable Timers Promises API is probably one of the most interesting for average developers, and it will be used most.

Do you remember the evolution of async code management?

Callbacks → Promises → Generators → Async/await

For some unclear reasons, setTimeout function was stuck for years and years in callback syntax and we had to deal with it in such a way:

console.log('It will be printed 1-st');function oldStyleMethod() {
setTimeout(() => {
console.log('It will be printed 3-rd with delay');
}, 5000);
oldStyleMethod();console.log('It will be printed 2-nd');

It’s a workable solution. The one that we got used to. But it looks messy. If we need to put a couple of timeouts 1 after another, then we’ll stuck in callback hell.

Somebody was fighting with it by wrapping timer in Promises:

await new Promise(resolve => setTimeout(resolve, 1000))

But no we have a better and much more cleaner way!

setTimeout — new way:

With the help of Node.js development team, we are now able to use async/await syntax while dealing with setTimeout() functions.

This feature was initially implemented in Node v.15, but since version 16 it’s in stable status and ready to go. The initial example above may be improved to:

import {setTimeout} from "timers/promises";console.log('It will be printed 1-st');async function newStyleDelay() {
await setTimeout(5000);
console.log('It will be printed 3-rd with delay');
newStyleDelay();console.log('It will be printed 2-nd');

With this new syntax, waiting for a timer looks almost the same as traditional sleep call in a synchronous language.

Now, we don’t have a headache if a couple of timers are required to be run sequentially. Just add await setTimeout(…); each time you need it and forget about the nesting hell.

The only thing we need to keep in mind — is that classic setTimeout function is declared globally and we can use it in any place of our code. But now, if we want to use its async/await version, we need to import it from “timers/promises” module.


You can already try to play with Timers Promises API in your Node environment. It’s quite simple and convenient to use.

But beware, it’s recommended by Node.js development team to use it in production applications only after it enters Active LTS stage, that is planned for October 25, 2021.

Senior Front-End developer in Backbase, Amsterdam