Node.js 15の新機能は何ですか?

Node.jsの15番目のバージョンの新機能に関する詳細を含む記事の翻訳を共有しています。


Node.jsバージョン 15は2020年10月20にリリースされました。主な変更点は次のとおりです。



  • 未処理の偏差に対するスローモード
  • 言語機能V88.6
  • NPM 7
  • 実験的なQUICサポート
  • N-APIバージョン7
  • 非同期ローカルストレージAPIのファイナライズ


これらのイノベーションとは何か、そしてそれらをどのように使用できるかを詳しく見てみましょう。



ノードの概要にNVMを使用する



では 前の記事、私たちは、使用するための指示を渡った NVM(ノードバージョンマネージャ)のNode.jsとNPMのバージョンを管理します。Node.js12.16.0とNPM6.14.8が環境にインストールされています。nvm install nodeを実行 することで、Node.js15.4.0とNPM7.0.15をインストールしました。



2つのウィンドウが開いています。1つ



Node.js12で、もう1つ Node.js15です。node12ウィンドウでは



$ nvm use 12
Now using node v12.16.0 (npm v6.14.8)
      
      





node15ウィンドウの場合



$ nvm use 15
Now using node v15.4.0 (npm v7.0.15)
      
      





これで、このバージョンを調査できます。



未処理のPromise拒否でモードをスローする



unhandledRejectionイベントは 、promiseが拒否され、イベントループ中にエラーハンドラーがpromiseにアタッチされないたびに発生します。 Node.jsの15の通り、デフォルトモード unhandledRejectionがいるから変更されて 警告して 投げますスローモード では、unhandledRejectionフック設定されていない 場合 catchメソッドでキャッチされない例外としてunhandledRejectionがスローさます。 エラーメッセージでpromiseを拒否するプログラムを作成します。







function myPromise() {
  new Promise((_, reject) =>
    setTimeout(
      () =>
        reject({
          error: 'The call is rejected with an error',
        }),
      1000
    )
  ).then((data) => console.log(data.data));
}

myPromise();
      
      





このコードをnode12ウィンドウで実行する と、長い警告メッセージが表示されます。



$ 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.
      
      





このコードをウィンドウnode15で実行すると、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'
}
      
      





以下のコードのthenブランチエラーハンドラーを追加します .catch(( error )=> console.log( error .error))も機能します)。



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();
      
      





これで、コードは両方のウィンドウ(node12node15)で正しく実行されます



$ node myPromise.js
The call is rejected with an error
      
      





promiseのエラーハンドラーを作成することをお勧めします。ただし、catch方式ではエラーがキャッチされない場合があります。潜在的なエラーを検出するために、unhandledRejectionフックを設定することをお勧めします。



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
});
      
      





unhandledRejectionフックがインストールされたら、Node.jsの12とNode.jsの15の両方で動作し、 unhandledRejectionがされ、必要に応じて処理されます。



$ 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' } }
      
      





V88.6新しい言語機能



V8、JavaScriptエンジン、8.4から8.6に更新。バージョン。パフォーマンスを向上させるためのさまざまな調整に加えて、新しいV8には次の機能があります。



  • Promise.any()およびAggregateError(V8 8.5以降)
  • setTimeoutAbortControllerを待つ(実験的)
  • String.prototype.replaceAll()(V8 8.5以降)
  • 論理代入演算子&& =|| =および?? =(V8 8.5以降)


Promise.any()およびAggregateError



まず、既存のPromise.all()メソッドを見てみましょう



Promise.all()は、promiseからiterableを入力として受け取り、単一のpromiseを返します。これは、入力promiseの結果の配列として実行されます。



次のプログラムは、2つの解決されたpromiseでPromise.all()呼び出します



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();

      
      





Promise.all()は、すべての入力Promiseが解決されたとき、またはiterableにPromiseが含まれていない場合に実行されるPromiseを返します。



$ node myPromise.js
[
  { data: 'The data from 5000 ms delay' },
  { data: 'The data from 100 ms delay' }
]
      
      





次のプログラムは、2つの拒否されたpromiseでPromise.all()呼び出します



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()は、実行時に入力Promiseの拒否またはエラーを即座に拒否し、このエラーに関するメッセージを返します。



$ node myPromise.js
{ error: 'The error from 100 ms delay' }
      
      





Promise.any()はNode.js 15の新しいメソッドです。これはPromise.all()の反対です Promise.any()は、Promiseオブジェクトを含む反復可能オブジェクトを受け入れます。そして、iterableのPromiseの1つが成功するとすぐに、メソッドは実行されたpromiseの値を持つ単一のpromiseを返します。



次のプログラムは、2つの解決されたpromiseでPromise.any()呼び出します



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()は、最初に解決されたpromiseを返します。



$ node myPromise.js
{ data: 'The error from 100 ms delay' }
      
      





次のプログラムは、2つの拒否されたpromiseでPromise.any()呼び出します



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();
      
      





iterableのpromiseが失敗した場合、つまり 与えられたすべてのプロミスは拒否され、返されたプロミスは個々エラーをグループ化するErrorの新しいサブクラスであるAggregateError拒否され ます。



$ node myPromise.js
[AggregateError: All promises were rejected]
[
  { error: 'The error from 5000 ms delay' },
  { error: 'The error from 100 ms delay' }
]
      
      





setTimeoutとAbortControllerを待つ



前の例では、promise呼び出し内でsetTimeoutを使用しました



SetTimeoutWindowOrWorkerGlobalScopeは、コールバックを使用しています。ただし、 timers / promiseは、async / awaitで使用できるsetTimeoutの約束されたバージョンを提供し ます



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は、1つ以上のWebリクエストを自由に中止できるJavaScriptオブジェクトです。useAsyncに関する別の記事で AbortControllerの使用例を 示しました



両方 のawaitのsetTimeoutAbortControllerは実験的な機能です。



String.prototype.replaceAll()



既存のString.prototype.replace()メソッドを見てみましょう



replace()は、パターン一致の一部またはすべてがreplacerで置き換えられた新しい文字列を返します。パターンは、文字列または正規表現にすることができます。プレースホルダーは、一致ごとに呼び出される文字列または関数にすることができます。



パターンが文字列の場合、最初に出現したものだけが置き換えられます。



'20+1+2+3'.replace('+', '-');
      
      





この演算子を使用すると、「20–1 + 2 +3」が得られ ます。



すべての「+」を「-」に置き換えるには、正規表現を使用する必要があります。



'20+1+2+3'.replace(/\+/g, '-');
      
      





上記の演算子を使用すると、「20-1-2-3」が得られ ます。 replaceAll()



メソッド はNode.js 15の新機能です。これを使用することで、正規表現を使用する必要がなくなります。このメソッドは、すべてのパターン一致がプレースホルダーに置き換えられた新しい文字列を返します。パターンは文字列または正規表現にすることができ、プレースホルダーは文字列または一致ごとに呼び出される関数にすることができます。 replaceAll()



メソッドのおかげで、 すべての「+」を「-」に置き換えるために正規表現を使用する必要はありません。



'20+1+2+3'.replaceAll('+', '-');
      
      





この演算子を実行すると、「20-1-2-3」が得られ ます。



論理代入演算子&& =、|| =および?? =



論理代入演算子ANDx && = y)は、xが真の場合にのみ代入演算を実行します。



X && = Yであると同等の X &&(X = Y)と同等ではなく、 X = X && Y



let x = 0;
let y = 1;

x &&= 0; // 0
x &&= 1; // 0
y &&= 1; // 1
y &&= 0; // 0
      
      





論理代入演算子OR(x || = y)は、xがfalseの場合にのみ代入演算を実行します。



x || = yはx同等です || (x = y)ただし、x = x ||と同等ではありません



let x = 0;
let y = 1;

x ||= 0; // 0
x ||= 1; // 1
y ||= 1; // 1
y ||= 0; // 1
      
      





論理代入演算子nullish(x ?? = y)は、xがNULL(nullまたは undefined)の場合にのみ代入演算を実行します



X?= Yであると同等の X?(x = y)、および x = x ??



let x = undefined;
let y = '';

x ??= null; // null
x ??= 'a value'; // "a value"
y ??= undefined; // ""
y ??= null; // ""
      
      





その他の変更



加えて、スローモード :未処理の約束を拒否し、新しいV8 8.6言語機能に、Node.jsの15は、以下の変更がある



NPM 7のパッケージとyarn.lockファイル、ワークスペースのサポートにピアの依存関係の自動インストールなどの多くの変更、改良を: 、など。これはすべて、この記事で参照により説明されてい ます



QUIC:HTTP / 3のプライマリプロトコルであるUDPトランスポート層の実験的サポート。QUICには、TLS 1.3による組み込みセキュリティ、フロー制御、エラー修正、接続移行、および多重化が含まれます。



N-APIバージョン7:カスタムアドオンを作成するためのAPI。基盤となるJavaScriptランタイムから独立しており、Node.jsの一部としてサポートされています。



Async Local Storage APIの機能強化:大規模アプリケーション向けの最新のロギングと機能分析の機能を提供します。



結論



Node.js 15の新しいバージョンには、非常に重要なものを含む、多数の新機能と改善点があります。



新しいバージョンを試して、プロジェクトを更新する準備をしてください。



ご清聴ありがとうございました!この記事がお役に立てば幸いです。



All Articles