ホームページ  >  記事  >  ウェブフロントエンド  >  Node.jsのブロッキングとノンブロッキングの説明

Node.jsのブロッキングとノンブロッキングの説明

不言
不言転載
2018-11-15 17:30:551863ブラウズ

この記事では、Node.js のブロックと非ブロックについて説明します。必要な方は参考にしていただければ幸いです。

ブロッキングと非ブロッキングの概要

この概要では、Node.js におけるブロッキング呼び出しと非ブロッキング呼び出しの違いについて説明します。この概要では、イベント ループと非ブロッキング呼び出しについて説明します。 libuv、これらのトピックに関する事前知識は必要ありません。JavaScript 言語と Node.js コールバック パターンの基本的な理解が前提となります。

「I/O」は主に、libuv によってサポートされるシステムのディスクおよびネットワークとの対話を指します。

ブロッキング

ブロッキングとは、Node.js プロセス内の他の JavaScript の実行が、非 JavaScript 操作が完了するまで待機する必要があることを意味します。これは、イベント ループが JavaScript の実行を続行できないために発生します。ブロッキング操作が発生します。

Node.js では、I/O などの JavaScript 以外の操作を待機するのではなく CPU を集中的に使用するためにパフォーマンスが低下する JavaScript は、通常、ブロッキングとは呼ばれません。 Node.js 標準ライブラリの libuv を使用した同期方法は、最も一般的に使用されるブロック操作であり、ネイティブ モジュールにもブロック メソッドがある場合があります。

Node.js 標準ライブラリのすべての I/O メソッドは、ノンブロッキングの非同期バージョンを提供し、コールバック関数を受け入れます。一部のメソッドには、名前が Syncend で始まる対応するブロッキング メソッドもあります。

コードの比較

ブロッキング メソッドは同期的に実行され、非ブロッキング メソッドは非同期的に実行されます。

ファイル システム モジュールを例に挙げると、これはファイルを同期的に読み取るメソッドです:

const fs = require('fs');
const data = fs.readFileSync('/file.md'); // blocks here until file is read

これは同等の非同期の例です:

const fs = require('fs');
fs.readFile('/file.md', (err, data) => {
  if (err) throw err;
});

最初の例より簡単に見えます。 2 番目の例ですが、欠点は、2 行目により、ファイル全体が読み取られるまで他の JavaScript が実行されなくなることです。同期バージョンでは、エラーがスローされた場合はそれをキャッチする必要があり、そうしないとプロセスがクラッシュすることに注意してください。 、非同期バージョンでは、図のようにエラーをスローするかどうかは作成者次第です。

この例を少し拡張してみましょう:

const fs = require('fs');
const data = fs.readFileSync('/file.md'); // blocks here until file is read
console.log(data);
// moreWork(); will run after console.log

これは類似していますが同等ではない非同期の例です:

const fs = require('fs');
fs.readFile('/file.md', (err, data) => {
  if (err) throw err;
  console.log(data);
});
// moreWork(); will run before console.log

上記の最初の例では、console .logmoreWork() の前に呼び出されます。2 番目の例では、fs.readFile() は非ブロッキングであるため、JavaScript の実行を続行できます。また、moreWork () が最初に呼び出されます。ファイルの読み取りが完了するのを待たずに moreWork() を実行できる機能は、スループットを向上させるための重要な設計上の選択です。

同時実行性とスループット

Node.js での JavaScript の実行はシングルスレッドであるため、同時実行性とは、他の作業 (実行される任意のコード) の完了後に JavaScript コールバック関数を実行するイベント ループの機能を指します。同時に、JavaScript 以外の操作 (I/O など) が行われている間もイベント ループの実行を継続できるようにする必要があります。

例として、各 Web サーバー リクエストの完了に 50 ミリ秒かかる状況を考えてみましょう。50 ミリ秒のうちの 45 ミリ秒は、非同期で完了できるデータベース I/O であり、ノンブロッキングの非同期操作を選択すると、各リクエストを解放できます。ブロッキング方式ではなくノンブロッキング方式を選択するだけで、他のリクエストの処理に 45 ミリ秒かかります。これは容量に大きな違いがあります。

イベント ループは、同時作業を処理するために追加のスレッドを作成できる他の多くの言語のモデルとは異なります。

ブロッキング コードとノンブロッキング コードを混合する危険性

I/O を処理するときに避けるべきパターンがいくつかあります。例を見てみましょう:

const fs = require('fs');
fs.readFile('/file.md', (err, data) => {
  if (err) throw err;
  console.log(data);
});
fs.unlinkSync('/file.md');

上記の例では、 fs .unlinkSync() は fs.readFile() の前に実行される可能性が高く、実際に読み取る前に file.md を削除します。より良い書き込み方法は、完全にノンブロッキングであり、正しい方法で実行されることが保証されています。 order:

const fs = require('fs');
fs.readFile('/file.md', (readFileErr, data) => {
  if (readFileErr) throw readFileErr;
  console.log(data);
  fs.unlink('/file.md', (unlinkErr) => {
    if (unlinkErr) throw unlinkErr;
  });
});

上記のコードでは、fs.readFile() のコールバックで fs.unlink() へのノンブロッキング呼び出しが行われ、操作の正しい順序が保証されます。

以上がNode.jsのブロッキングとノンブロッキングの説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はhttps://segmentfault.com/a/1190000017016894で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。