Nodejs のイベントとイベント ループを理解する
関連する推奨事項: 「nodejs チュートリアル 」
JavaScript に精通している友人は、マウスの移動、マウスのクリック、キーボード入力など。 JavaScript でこれらのイベントをリッスンして、対応する処理をトリガーします。
nodejs にもイベントがあり、特殊な処理を行うための特別なイベント モジュールもあります。
同時イベントとイベント ループも、nodejs で非同期 IO を構築するための非常に重要な概念です。
今日はそれについて詳しく学びます。
イベント
nodejs は、イベント用の特別なモジュール lib/events.js を提供します。
nodejs を使用して Web サーバーを構築することについて話していたときのことを覚えていますか?
const server = http.createServer((req, res) => { res.statusCode = 200 res.setHeader('Content-Type', 'text/plain') res.end('welcome to www.flydean.com\n') })
ここでは、各リクエストがリクエスト イベントをトリガーします。
nodejs のコア API は非同期イベント駆動型アーキテクチャに基づいているため、nodejs には多くのイベントがあります。
例: net.Server は新しい接続が確立されるたびにイベントをトリガーし、fs.ReadStream はファイルが開かれたときにイベントをトリガーし、stream はデータが読み取り可能になったときにイベントをトリガーします。
nodejs イベントを構築する方法を見てみましょう:
const EventEmitter = require('events') const eventEmitter = new EventEmitter()
イベントには一般的に使用される 2 つのメソッド、つまり on と Emit があります。
on はイベントをリッスンするために使用され、emit はイベントをトリガーするために使用されます。
eventEmitter.on('fire', () => { console.log('开火') }) eventEmitter.emit('fire')
emit はパラメータを取ることもできます。次のパラメータを見てみましょう:
eventEmitter.on('fire', who => { console.log(`开火 ${who}`) }) eventEmitter.emit('fire', '美帝')
2 つのパラメータを見てみましょう:
eventEmitter.on('fire', (who, when) => { console.log(`开火 ${who} ${when}`) }) eventEmitter.emit('fire', '川建国','now')
デフォルトでは、EventEmitter は次で始まります。登録された順序で同期的に呼び出されます。これにより、イベントの正しい順序が保証され、競合状態やロジック エラーを回避できます。
非同期実行が必要な場合は、setImmediate() または process.nextTick() を使用して非同期実行モードに切り替えることができます。
eventEmitter.on('fire', (who, when) => { setImmediate(() => { console.log(`开火 ${who} ${when}`); }); }) eventEmitter.emit('fire', '川建国','now')
さらに、イベントは他のいくつかのメソッドもサポートしています:
once(): 単一のリスナーを追加します
removeListener() / off(): From イベント リスナーを削除しますevents
removeAllListeners(): すべてのイベント リスナーを削除します
イベント ループ
nodejs コードがシングルスレッド環境で実行されることはわかっています。はい、処理されるのは 1 つだけです。一度に。
この処理方法により、マルチスレッド環境におけるデータ同期の問題が回避され、処理効率が大幅に向上します。
いわゆるイベント ループとは、プログラム サイクルにおいて、プロセッサがこのサイクルのイベントを処理した後、次のイベント サイクルに入り、次のイベント サイクルのイベントを処理することを意味します。サイクルごとに。
イベント ループのブロック
イベント処理中にイベントの処理がブロックされると、他のイベントの実行に影響を与えるため、JS ではほぼすべての IO が非処理であることがわかります。 -ブロッキング。これが、JavaScript に非常に多くのコールバックが存在する理由でもあります。
イベント ループの例
簡単なイベント ループの例を見てみましょう:
const action2 = () => console.log('action2') const action3 = () => console.log('action3') const action1 = () => { console.log('action1') action2() action3() } action1()
上記のコード出力:
action1 action2 action3
スタックとメッセージ キュー
関数間の呼び出しはスタックを通じて実装されることがわかっています。上記の例では、呼び出しシーケンスもスタックを通じて実装されています。
ただし、関数内のすべてのメソッドがスタックにプッシュされるわけではなく、一部のメソッドはメッセージ キューに入れられます。
別の例を挙げてみましょう:
const action2 = () => console.log('action2') const action3 = () => console.log('action3') const action1 = () => { console.log('action1') setTimeout(action2, 0) action3() } action1()
上記のコードを実行した結果は次のとおりです:
action1 action3 action2
結果は異なります。これは、settimeout がタイマーをトリガーするためで、タイマーが期限切れになると、コールバック関数はスタックに置かれるのではなく、処理されるメッセージ キューに置かれます。
イベント ループはスタック内のイベントに優先順位を付けます。スタックにデータがない場合にのみ、メッセージ キュー内のイベントの消費に切り替わります。
上記の例の setTimeout のタイムアウト時間は 0 ですが、action3 を実行するには、action3 が実行されるまで待つ必要があります。
setTimeout のタイムアウトは現在のスレッドで待機するのではなく、ブラウザまたは他の JS 実行環境によって呼び出されることに注意してください。
ジョブ キューとプロミス
ES6 のプロミスでは、ジョブ キューの概念が導入されています。ジョブ キューを使用すると、非同期関数の結果を最後に配置するのではなく、できるだけ早く実行します。呼び出しスタック。
例:
const action2 = () => console.log('action2') const action3 = () => console.log('action3') const action1 = () => { console.log('action1') setTimeout(action2, 0) new Promise((resolve, reject) => resolve('应该在action3之后、action2之前') ).then(resolve => console.log(resolve)) action3() } action1()
出力結果:
action1 action3 应该在action3之后、action2之前 action2
これは、現在の関数の終了前に解決された Promise が現在の関数の直後に実行されるためです。
つまり、最初にスタックが実行され、次にジョブ キューが実行され、最後にメッセージ キューが実行されます。
process.nextTick()
まず、tick という定義を説明します。tick はイベント サイクルを指します。 Process.nextTick() は、次のイベント ループ ティックが開始する前にこの関数を呼び出すことを指します。
process.nextTick(() => { console.log('i am the next tick'); })
したがって、nextTick はメッセージ キューの setTimeout よりも高速である必要があります。
setImmediate()
nodejs は、コードをできるだけ早く実行するための setImmediate メソッドを提供します。
setImmediate(() => { console.log('I am immediate!'); })
setImmediate の関数は、イベント ループの次の反復で実行されます。
setImmediate() と setTimeout(() => {}, 0) の関数は基本的に似ています。これらはすべて、イベント ループの次の反復で実行されます。
setInterval()
特定のコールバック関数を定期的に実行したい場合は、setInterval を使用する必要があります。
setInterval(() => { console.log('每隔2秒执行一次'); }, 2000)
要清除上面的定时任务,可以使用clearInterval:
const id = setInterval(() => { console.log('每隔2秒执行一次'); }, 2000) clearInterval(id)
注意,setInterval是每隔n毫秒启动一个函数,不管该函数是否执行完毕。
如果一个函数执行时间太长,就会导致下一个函数同时执行的情况,怎么解决这个问题呢?
我们可以考虑在回调函数内部再次调用setTimeout,这样形成递归的setTimeout调用:
const myFunction = () => { console.log('做完后,隔2s再次执行!'); setTimeout(myFunction, 2000) } setTimeout(myFunction, 2000)
更多编程相关知识,请访问:编程视频!!
以上がNodejs のイベントとイベント ループを理解するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









概要: C++ の非同期プログラミングを使用すると、時間のかかる操作を待たずにマルチタスクを行うことができます。関数ポインターを使用して、関数へのポインターを作成します。コールバック関数は、非同期操作が完了すると呼び出されます。 boost::asio などのライブラリは、非同期プログラミングのサポートを提供します。実際のケースでは、関数ポインターと boost::asio を使用して非同期ネットワーク リクエストを実装する方法を示します。

並行プログラミングのイベント駆動メカニズムは、イベントの発生時にコールバック関数を実行することによって外部イベントに応答します。 C++ では、イベント駆動メカニズムは関数ポインターを使用して実装できます。関数ポインターは、イベントの発生時に実行されるコールバック関数を登録できます。ラムダ式ではイベント コールバックを実装することもでき、匿名関数オブジェクトの作成が可能になります。実際のケースでは、関数ポインタを使用して GUI ボタンのクリック イベントを実装し、イベントの発生時にコールバック関数を呼び出してメッセージを出力します。

Java フレームワークでの非同期プログラミングにおける 3 つの一般的な問題と解決策: コールバック地獄: Promise または CompletableFuture を使用して、より直感的なスタイルでコールバックを管理します。リソースの競合: 同期プリミティブ (ロックなど) を使用して共有リソースを保護し、スレッドセーフなコレクション (ConcurrentHashMap など) の使用を検討します。未処理の例外: タスク内の例外を明示的に処理し、例外処理フレームワーク (CompletableFuture.Exceptionally() など) を使用して例外を処理します。

Go フレームワークは Go の同時実行性と非同期機能を使用して、同時タスクと非同期タスクを効率的に処理するためのメカニズムを提供します。 1. 同時実行性は Goroutine によって実現され、複数のタスクを同時に実行できます。 2. 非同期プログラミングはチャネルを通じて実装されます。メインスレッドをブロックせずに実行可能。 3. HTTP リクエストの同時処理、データベース データの非同期取得などの実用的なシナリオに適しています。

jQuery は、DOM 操作、イベント処理、アニメーション効果などを簡素化するために使用できる人気のある JavaScript ライブラリです。 Web 開発では、選択した要素のイベント バインディングを変更する必要がある状況によく遭遇します。この記事では、jQuery を使用して選択要素変更イベントをバインドする方法を紹介し、具体的なコード例を示します。まず、ラベルを使用してオプションを含むドロップダウン メニューを作成する必要があります。

1. 非同期プログラミングを使用する理由は何ですか?従来のプログラミングではブロッキング I/O が使用されます。つまり、プログラムは操作が完了するまで待機してから続行します。これは単一のタスクではうまく機能する可能性がありますが、多数のタスクを処理する場合にはプログラムの速度が低下する可能性があります。非同期プログラミングは、従来のブロッキング I/O の制限を破り、非ブロッキング I/O を使用します。つまり、プログラムは、タスクの完了を待たずに、タスクを別のスレッドまたはイベント ループに分散して実行できます。これにより、プログラムは複数のタスクを同時に処理できるようになり、プログラムのパフォーマンスと効率が向上します。 2. Python 非同期プログラミングの基礎 Python 非同期プログラミングの基礎は、コルーチンとイベント ループです。コルーチンは、関数の一時停止と再開を切り替えることができる関数です。イベントループはスケジュールを担当します

PHP での非同期プログラミングの利点には、スループットの向上、待ち時間の短縮、リソース使用率の向上、およびスケーラビリティが含まれます。欠点としては、複雑さ、デバッグの難しさ、ライブラリのサポートの制限などが挙げられます。実際のケースでは、WebSocket 接続の処理に ReactPHP が使用され、非同期プログラミングの実際的な応用例が示されています。

非同期プログラミング、英語の Asynchronous Programming とは、プログラム内の特定のタスクを、他のタスクの完了を待たずに同時に実行でき、それによってプログラムの全体的な動作効率が向上することを意味します。 Python では、asyncio モジュールは非同期プログラミングを実装するための主要なツールであり、コルーチン、イベント ループ、および非同期プログラミングに必要なその他のコンポーネントを提供します。コルーチン: コルーチンは、スレッドと同様に実行を一時停止してから再開できる特別な関数ですが、コルーチンはスレッドよりも軽量で、消費するメモリも少なくなります。コルーチンは async キーワードで宣言され、実行は await キーワードで一時停止されます。イベント ループ: イベント ループ (EventLoop) は非同期プログラミングの鍵です
