What's new in Node.js v16

Summary

Here’s changes in Node.js v16 for my memo.

Timers Promise API

import { setTimeout, setImmediate, setInterval } from "timers/promises";

let result;

result = await setTimeout(1000, "foo");
console.log(result);
//=> "foo"

result = await setImmediate("bar");
console.log(result);
//=> "bar"

const interval = 100;
for await (const startTime of setInterval(interval, Date.now())) {
  const now = Date.now();
  console.log(now);
  if (now - startTime > 1000) {
    break;
  }
}
console.log("FINAL: ", Date.now());
// 1631084713750
// 1631084713850
// 1631084713950
// 1631084714050
// 1631084714150
// 1631084714251
// 1631084714351
// 1631084714451
// 1631084714551
// 1631084714651
// FINAL:  1631084714651

AsyncLocalStorage

This is a kind of thread (request) local storage.

// async-storage.js
import { AsyncLocalStorage } from "async_hooks";

export const storage = new AsyncLocalStorage();

// fetch-users.js
import { storage } from "./async-storage.js";

export async function fetchUsers() {
  const reqId = storage.getStore().get("requestId");
  console.log("request: ", reqId);

  // dummy API request
  const users = await fetch("/users");
  return users.map((u) => ({ ...u, foo: "hoge" }));
}

// app.js
import express from "express";
import { v4 as uuid } from "uuid";

import { storage } from "./async-storage.js";
import { fetchUsers } from "./fetch-users.js";

const app = express();

app.get("/", (req, res) => {
  storage.run(new Map(), async () => {
    const reqId = uuid();
    storage.getStore().set("requestId", reqId);

    // `fetchUsers` can get `requestId` w/o argument passing.
    const users = await fetchUsers();
    res.json(users);
  });
});

app.listen(3000, () => {});

Corepack

# After installing Node.js >=16.9.0
$ corepack --version
0.9.0

# You can now use `yarn` and `pnpm` CLI commands.
$ corepack enable

# When you want to use different version of `yarn` outside of your project(s),
# install specific version globally.
$ corepack prepare yarn@3.0.1 --activate

V8 update

Array.prototype.at

v16.6.0

const array = [1, 2, 3];

array.at(-1);
//=> 3

Object.hasOwn

v16.9.0

const obj = { name: "mmyoji", sex: "male" };

Object.hasOwn(obj, "name");
//=> true

Error cause

v16.9.0

const error1 = new Error("Something wrong happens.");
const error2 = new Error("API Error", { cause: error1 });

error2.cause === error1; // true

References

Contents