Our Global Presence
Canada
57 Sherway St,
Stoney Creek, ON
L8J 0J3
India
606, Suvas Scala,
S P Ring Road, Nikol,
Ahmedabad 380049
USA
1131 Baycrest Drive,
Wesley Chapel,
FL 33544
In this article, we’re going to discuss about Node.js 15 new features, including throw on unhandled rejections and V8 8.6 language features.
Node.js 15 was released recently. It comes with a number of major features:
Let’s explore what they are and how to use them.
In a previous article, we provided instructions on using NVM (Node Version Manager) to manage Node.js and NPM versions. In our environment, we had Node.js 12.16.0 and NPM 6.14.8 installed. By running nvm install node, we installed Node.js 15.4.0 and NPM7.0.15.
We have two windows open, one is set to Node.js 12, and the other one is set to Node.js 15.
On the node12 window:
$ nvm use 12 Now using node v12.16.0 (npm v6.14.8)
On the node15 window:
$ nvm use 15 Now using node v15.4.0 (npm v7.0.15)
Now we’re ready to explore.
The unhandledRejection event is emitted whenever a promise is rejected and no error handler is attached to the promise within a turn of the event loop. Starting from Node.js 15, the default mode for unhandledRejection has been changed to throw from warn. In throw mode, if an unhandledRejection hook is not set, the unhandledRejection is raised as an uncaught exception.
Create a program so that a promise is rejected with an error message:
function myPromise() { new Promise((_, reject) => setTimeout( () => reject({ error: 'The call is rejected with an error', }), 1000 ) ).then((data) => console.log(data.data)); } myPromise();
When you run this code on node12 window it shows a long warning message:
$ node myPromise.js (node:79104) UnhandledPromiseRejectionWarning: #<Object> (node:79104) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1) (node:79104) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.Users that have an unhandledRejection hook should see no change in behavior, and it’s still possible to switch modes using the --unhandled-rejections=mode process flag.
Run this code on the node15 window and it throws the error, UnhandledPromiseRejection
:
$ node myPromise.js node:internal/process/promises:227 triggerUncaughtException(err, true /* fromPromise */); ^ [UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "#<Object>".] { code: 'ERR_UNHANDLED_REJECTION' }
Add an error handler in the then clause in the below code (.catch((error) => console.log(error.error)) works too).
function myPromise() { new Promise((_, reject) => setTimeout( () => reject({ error: 'The call is rejected with an error', }), 1000 ) ).then( (data) => console.log(data.data), (error) => console.log(error.error) ); } myPromise();
Now, the code runs correctly on both node12 and node15 windows:
$ node myPromise.js The call is rejected with an error
It’s best practice to write an error handler for promises. However, there will be cases where errors are not caught. It’s a good idea to set up the unhandledRejection hook to catch potential errors.
function myPromise() { new Promise((_, reject) => setTimeout( () => reject({ error: 'The call is rejected with an error', }), 1000 ) ).then((data) => console.log(data.data)); } myPromise(); process.on('unhandledRejection', (reason, promise) => { console.log('reason is', reason); console.log('promise is', promise); // Application specific logging, throwing an error, or other logic here });
The unhandledRejection hook works for both Node.js 12 and Node.js 15. With that set up, unhandledRejection can be handled properly.
$ node myPromise.js reason is { error: 'The call is rejected with an error' } promise is Promise { <rejected> { error: 'The call is rejected with an error' } }
The V8 JavaScript engine has been updated from 8.4 to 8.6. Along with performance tweaks and improvements, the V8 update also brings the following language features:
First, let’s take a look at the existing Promise.all() method.
Promise.all() takes an iterable of promises as an input and returns a single promise that resolves to an array of the results of the input promises.
The following program calls Promise.all() on two resolved promises:
function myPromise(delay) { return new Promise((resolve) => setTimeout( () => resolve({ data: `The data from ${delay} ms delay`, }), delay ) ); } async function getData() { try { const data = await Promise.all([myPromise(5000), myPromise(100)]); console.log(data); } catch (error) { console.log(error); } } getData();
The Promise.all() returned promise will resolve when all of the input’s promises have resolved, or if the input iterable contains no promises:
$ node myPromise.js [ { data: 'The data from 5000 ms delay' }, { data: 'The data from 100 ms delay' } ]
The following program calls Promise.all() on two rejected promises.
function myPromise(delay) { return new Promise((_, reject) => setTimeout( () => reject({ error: `The error from ${delay} ms delay`, }), delay ) ); } async function getData() { try { const data = await Promise.all([myPromise(5000), myPromise(100)]); console.log(data); } catch (error) { console.log(error); } } getData();
Promise.all() immediately rejects any of the input promises rejecting or non-promises throwing an error, and will reject with this first rejection message or error:
$ node myPromise.js { error: 'The error from 100 ms delay' }
Promise.any() is new in Node.js 15. This is the opposite of Promise.all(). It takes an iterable of promises and, as soon as one of the promises in the iterable fulfills, returns a single promise that resolves with the value from that promise.
The following program calls Promise.any() on two resolved promises:
function myPromise(delay) { return new Promise((resolve) => setTimeout( () => resolve({ data: `The error from ${delay} ms delay`, }), delay ) ); } async function getData() { try { const data = await Promise.any([myPromise(5000), myPromise(100)]); console.log(data); } catch (error) { console.log(error); console.log(error.errors); } } getData();
Promise.any() returns the first resolved promise:
$ node myPromise.js { data: 'The error from 100 ms delay' }
The following program calls Promise.any() on two rejected promises:
function myPromise(delay) { return new Promise((_, reject) => setTimeout( () => reject({ error: `The error from ${delay} ms delay`, }), delay ) ); } async function getData() { try { const data = await Promise.any([myPromise(5000), myPromise(100)]); console.log(data); } catch (error) { console.log(error); console.log(error.errors); } } getData();
If no promises in the iterable are fulfilled — i.e. all of the given promises are rejected — the returned promise is rejected with an AggregateError, a new subclass of Error that groups together individual errors.
$ node myPromise.js [AggregateError: All promises were rejected] [ { error: 'The error from 5000 ms delay' }, { error: 'The error from 100 ms delay' } ]
In the previous examples, we used setTimeout inside the promise call. The WindowOrWorkerGlobalScope’s setTimeout uses a callback. However, timers/promises provides a promisified version of setTimeout, which can be used with async/await.
const { setTimeout } = require('timers/promises'); async function myPromise(delay) { await setTimeout(delay); return new Promise((resolve) => { resolve({ data: `The data from ${delay} ms delay`, }); }); } async function getData() { try { const data = await Promise.any([myPromise(5000), myPromise(100)]); console.log(data); } catch (error) { console.log(error); console.log(error.errors); } } getData();
AbortController is a JavaScript object that allows us to abort one or more web requests as and when desired. We gave examples of how to use AbortController on the topic of useAsync.
Both await setTimeout and AbortController are experimental features.
First, let’s take a look at the existing String.prototype.replace() method.
replace() returns a new string with some or all matches of a pattern replaced by a replacement. The pattern can be a string or a regular expression. The replacement can be a string or a function to be called for each match.
If the pattern is a string, only the first occurrence will be replaced.
'20+1+2+3'.replace('+', '-');
Executing the above statement will yield “20–1+2+3”.
In order to replace all ‘+’ with ‘-’, a regular expression has to be used.
'20+1+2+3'.replace(/\+/g, '-');
Execute the above statement will yield “20–1-2-3”.
replaceAll() is new in Node.js 15 to avoid using the regular expression. It returns a new string with all matches of a pattern replaced by a replacement. The pattern can be a string or a regular expression and the replacement can be a string or a function to be called for each match.
With replaceAll(), we do not have to use a regular expression to replace all ‘+’ with ‘-’.
'20+1+2+3'.replaceAll('+', '-');
Executing the above statement will yield “20–1-2-3”.
Logical assignment operators &&=, ||=, and ??=
A few logical assignment operators have been added to Node.js 15.
The logical AND assignment (x &&= y) operator only assigns if x is truthy. x &&= y is equivalent to x && (x = y), and it is not equivalent to x = x && y.
let x = 0; let y = 1; x &&= 0; // 0 x &&= 1; // 0 y &&= 1; // 1 y &&= 0; // 0
The logical OR assignment (x ||= y) operator only assigns if x is falsy. x ||= y is equivalent to x || (x = y), and it is not equivalent to x = x || y.
let x = 0; let y = 1; x ||= 0; // 0 x ||= 1; // 1 y ||= 1; // 1 y ||= 0; // 1
The logical nullish assignment (x ??= y) operator only assigns if x is nullish (null or undefined). x ??= y is equivalent to x ?? (x = y), and it is not equivalent to x = x ?? y.
let x = undefined; let y = ''; x ??= null; // null x ??= 'a value'; // "a value" y ??= undefined; // "" y ??= null; // ""
For more information and to develop web application using Node JS, Hire Node Developer from us as we give you a high-quality product by utilizing all the latest tools and advanced technology. E-mail us any clock at – hello@hkinfosoft.com or Skype us: “hkinfosoft”. To develop custom web apps using Node JS, please visit our Hire Node Developer technology page.
Content Source:
57 Sherway St,
Stoney Creek, ON
L8J 0J3
606, Suvas Scala,
S P Ring Road, Nikol,
Ahmedabad 380049
1131 Baycrest Drive,
Wesley Chapel,
FL 33544
57 Sherway St,
Stoney Creek, ON
L8J 0J3
606, Suvas Scala,
S P Ring Road, Nikol,
Ahmedabad 380049
1131 Baycrest Drive,
Wesley Chapel,
FL 33544
© 2024 — HK Infosoft. All Rights Reserved.
© 2024 — HK Infosoft. All Rights Reserved.
T&C | Privacy Policy | Sitemap