2017-01-06 17 views
1

私はNode jsプログラミングの初心者です。したがって、コアの概念とプラクティスを非常に適切に理解したいと思っています。 AFAIKノードjsには非ブロックI/Oがあり、ディスクやその他のI/O操作は非同期で実行され、JSはEvent Loopを使用してリソースと実行パスを管理する単一スレッドで実行されます。多くの場所で提案されているように、開発者はコールバックパターンを使用してカスタム関数/メソッドを書くことをお勧めします。ノードJSのイベントループブロッキングと非同期プログラミング

function processData(inputData, cb){ 
    // do some computation and other stuff 

    if (err) { 
    cb(err, null); 
    }else{ 
    cb(null, result); 
    } 
} 
callback = function(err, result){ 

// check error and handle 

// if not error then grab result and do some stuff 
} 

processData(someData, callback) 
// checking whether execution is async or not 
console.log('control reached at the end of block'); 

このコードを実行すると、すべてが最後にコンソールメッセージを同期して実行されます。私が信じていたのは、コンソールメッセージが最初に印刷され、続いてコールバック関数を呼び出すprocessData関数コードが実行されたということでした。そして、このように起こった場合、イベントループはブロックされず、最終的な応答が 'コールバック'機能によって準備されたときにのみ、リクエストに対する応答を実行します。

私の質問は次のとおりです。 - ノードの性質に応じて実行順序は問題ないのですか?何か間違っているのですか重要な概念がありませんか?

あなたのお役に立てれば助かりますか?

答えて

1

JavaScriptは他の言語と同様に、順番に実行されます。あなたは

var x = 1; 
x *= 2; 
x += 1; 

を書く場合は、結果は3、ない4ことを期待しています。それはかなり悪いことです。機能も同じです。あなたが書くとき

foo(); 
bar(); 

非常に同じ順序で実行することを期待します。関数をネストすると、これは変わりません。

var foo = function() {}; 
var bar = function(clb) { 
    clb(); 
    foo(); 
}; 
var callback = function() { 
}; 
bar(callback); 

期待される実行シーケンスはbar -> callback -> fooです。

人々がインターネット上で最も大きな被害を受けるのは、非同期プログラミングとコールバックパターンの間に等号を置くことです。 これは間違っていますです。コールバックパターンを使用する多くの同期関数があります。 Array.prototype.forEach()

本当に起こるのは、NodeJSがこのイベントループをフードの下に持つということです。複数の特殊機能を呼び出すことで、何かをスケジュールして後で実行することができます。setTimeoutsetIntervalprocess.nextTickすべてのI/Oは、イベントループで実行される予定のスケジュールも作成します。今、あなたは

var foo = function() {}; 
var bar = function(clb) { 
    procress.nextTick(clb); // <-- async here 
    foo(); 
}; 
var callback = function() { 
}; 
bar(callback); 

をすれば、予想される実行シーケンスは、このbar -> (schedule callback) -> fooされ、その後callback(他のすべてのキューに入れられたタスクを処理する、すなわち時に)いくつかの点で発生します。

これはかなり機能しています。

+0

だから、setTimeOutや他の遅延/遅延タイミング関数の中に通常のコード(開発者によって書かれた)をラップすると、コントロールはすぐそこから次の実行ラインに戻ります。したがってこのメソッドはイベントループが次のリクエストに出席するためのスペースを確保しますキュー。したがって、ノードjでは、開発者コードの大部分をラップするか、非ブロッキングコードの実行を可能にするためにこれらの特別な関数を使用する必要がありますか? – iThirst

+0

@iThirst非ブロッキングコードを許可するには、**特別な機能を使用する必要があります。ただし、多くのライブラリ(データベースドライバなど)があなたのためにそれを行います。イベントループはCレベルからアクセスすることもできます(Cプラグインを作成している場合)。また、非ブロッキングコードが本当に必要かどうかは、コンテキストによって異なります。たいていの場合(つまりdbのような外部リソースを使用していないとき)、あなたはそれなしでも問題ありません。 – freakish

+0

したがって、I/Oを含まないコードは、イベントループのブロックに顕著な影響を与えないことが判明しました。また、私はDBの相互作用のためのmongooseライブラリを使用して、上記のようなコードを使用して非同期実行を評価しました。しかし、その場合もコンソールが最後に印刷され、mongooseコードが最初に実行されます。 mongooseは、コールバックにコールバックを提供した後でさえも非ブロッキングの方法で非同期で実行されますか? – iThirst

関連する問題