node.jsの初心者、イベントよりもコールバックを使用することで得られる利点は何ですか?


24

私は初心者のJavaScripterであり、V8エンジンの内部で何が起こっているのかを実際に知りません。

そうは言っても、node.js環境への初期の取り組みを本当に楽しんでいますが、グローバルイベントを生成する手段として、常にイベントを使用しています。 Objective-CまたはPythonプログラムで言うようなパターン。

私はいつもこのようなことをしていることに気付きます:

var events = require('events');

var eventCenter = new events.EventEmitter();

eventCenter.on('init', function() {
    var greeting = 'Hello World!';
    console.log('We're in the init function!);
    eventCenter.emit('secondFunction', greeting);
});

eventCenter.on('secondFunction', function(greeting) {
        console.log('We're in the second function!);
        console.log(greeting);
    eventCenter.emit('nextFunction');
});

eventCenter.on('nextFunction', function {
    /* do stuff */
});

eventCenter.emit('init');

したがって、実際には、「非同期」のnode.jsコードを、期待どおりの順序で処理するコードに構造化するだけです。代わりに、それが理にかなっている場合は、「逆コーディング」のようなものです。これをパフォーマンス重視または哲学重視のコールバック重視で行うことに違いはありますか?イベントの代わりにコールバックを使用して同じことを行う方が良いですか?


コールバックを頻繁に使用することでコードが読みにくくなる場合は、フレームワークを使用してコールバックの使用をラップすることを検討してください。少し調整が必要ですが、約束はしばしばoftenいコールバックを解くことができます。JQueryを使用している場合は、Deferredを使用できます。最も単純なpromiseフレームワークの1つはRSVPです。
ブライアン

私は混乱しています。あなたのコードには非同期なものは何もありません。単に関数呼び出しが複雑すぎて書かれているだけです。
svick

回答:


27

コールバックの良いところは、そこにグローバルな状態がなく、パラメーターを渡すことは簡単なことです。関数がある場合、download(URL, callback: (FileData)->void)それは本質的に「これをつかんでそれを行う」関数を構築できる自己完結型の高次関数であることがわかります。他の誰もそのコールバックのハンドルさえ持っておらず、そのコールバックは親関数の与えられたパラメーター以外は何も知らないので、コードフローが期待どおりであることを確認できます。これにより、モジュール化され、テストが容易になります。

5つのファイルを並行してダウンロードしてさまざまなことをしたい場合、適切なコールバック関数でこれらの関数のうち5つを実行するだけで済みます。優れた匿名関数構文を備えた言語では、これは非常に強力です。

一方、イベントは、1..*ユーザーに何らかの状態の変化を通知するように設計されています。の最後に「ダウンロード完了」イベントdownload(URL)を起動するprocessDownload()と、データの検索場所を認識して起動し、物事の実装をより多くの状態に結び付けます。ダウンロードを今どのように並列化しますか?異なるダウンロードを異なる方法でどのように処理しますか?あるdownload(URL, eventId)エレガントな?あるdownloadAndDoThing(URL)エレガントな?ほとんどない。

もちろん、すべてのものと同様に、あなたはトレードオフを行っています。ネストされたコールバックは、コードの実行順序をより混乱させる可能性があります。また、簡単にグローバルにアクセスできないため、1..*プロデューサーとコンシューマーの間に関係がある場合に、コードの選択が貧弱になります。データをやり取りするのに苦労しますが、追加の状態を持たずに済ますことができれば、それは通常とにかく利点です。

とにかく。コールバックが慣用的なnode.jsでコーディングしており、言語とライブラリはそれらの使用を中心に設計されています。あるデザインでも別のデザインでも利点が見られるかどうかに関係なく、どの言語でも慣用コードを書くことは、それを回避しようとするよりもはるかに大きなサポートを持ち、あなたの人生をはるかに楽にすることはほぼ常に真実だと思います


2

NodeJSでイベントを使用したことはありませんが、通常、クライアントサイドJSイベントを使用するのは、AppointmentBookedEventなどの何かが発生したことを通知するためです。これにより、SPAビューのさまざまな部分がパネルなどで)。
しかし、イベントを使用してメソッドが完了したことを通知することは、危険な旅の道です。イベントが発生したのと同じ順序で到着するようにイベントに依存することはできないため、あらゆる種類のランダム性につながる可能性
があります... イベントの使用には何の問題もありませんが、特定のレベルの粒度を下回ってはいけません; ドメインのようなイベントにこだわるなら、それで問題ありません。しかし、メソッドが終了したことを通知するのは細かすぎます。


0

あなたが探検するかもしれない何かは、それらを発しているオブジェクトの外側のイベントの使用法です。あなたの例でeventCenterは、独自のイベントを発行および処理するように見えます。他のオブジェクトがイベントの処理を開始した場合、アプリケーションの構造がどのように変化するかを検討してください。

したがって、eventCenter他のオブジェクトがスタートアップコードなどを処理するために処理できる「init」を発行する可能性があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.