初心者のチュートリアルでは、ノンブロッキングの性質は、通常、ブロッキングの例(return
ステートメントを使用)とノンブロッキングのノードの例(コールバックを使用)を示しています。たとえば、hereを参照してください。ブロックコードは常にreturn文を使用し、ノンブロッキングコードは常にコールバックを使用しますか?
return
を使用してノードアプリケーションにブロックコードを作成し、コールバックを使用してそのコードをやり直す方法を見つけることを「匂い」として取るべきでしょうか?
初心者のチュートリアルでは、ノンブロッキングの性質は、通常、ブロッキングの例(return
ステートメントを使用)とノンブロッキングのノードの例(コールバックを使用)を示しています。たとえば、hereを参照してください。ブロックコードは常にreturn文を使用し、ノンブロッキングコードは常にコールバックを使用しますか?
return
を使用してノードアプリケーションにブロックコードを作成し、コールバックを使用してそのコードをやり直す方法を見つけることを「匂い」として取るべきでしょうか?
TL; DR:コードが「長い」時間がかかる可能性がある場合、それはコールバックでそれを処理するために、より効率的/クリーナーであってもよいです。
リターン/ノーリターンではなく、コードが実際に行うことです。
例の関数はをブロックしません。に戻ります。db.query
は任意の時間がかかりますので、ブロックします。その間に他のことをしたい場合は、すぐに戻り、結果処理をコールバックで行います。
は、実際に何が起こっているか、コールバックに渡された(返された)データなどの影響を受けるか、依存するかによって異なります。
ブロッキングコールは通常、呼び出しによって引き起こされた「アクション」の後にリターンが発生するため何かを返します。したがって、アクションの成功または失敗に関する情報とアクションによって生成されたデータを返すことができます。これは、本来ブロックしないが、I/Oをしないコールにも適用されるので、コールバックは必要ありません。
ファイルを読み込む関数のような非ブロッキング呼び出しは、通常、何か重要なことをする前に戻り値を返すので、戻り値を使用する傾向はありません。代わりに、コールバックを呼び出して、生成されたデータがあればそれを送信します。エラーメッセージも送信されます。
非ブロッキング呼び出しの主な動機は、外部プロセスまたはデバイスが戻るのを待っているため、スレッドの制御を解放して他の操作を「待機中」に実行できるようにすることです。
コールバックを使用する非ブロッキング/非同期コードは、書き込み、読み取り、および保守が難しいため、アプリケーションのパフォーマンスとスケーラビリティに違いがある場合を除いて、ノンブロッキングコードを避ける必要があります。使用しているAPIで必要です。
は、この比較的愚かな例を考えてみましょう:
function add(a,b,cb) { cb(a+b); }
console.log('2+2 is', add(2,2)); // -> 4
function add(a,b) { return a+b; }
add(2,2,function(sum) { console.log('2+2 is', sum); }); // -> 4
最初のものは、目に公正少し簡単です。
多くのノードAPIには非同期バージョンがありますが、同期バージョンはありません。これらのAPIを使用する場合は、コードを非同期にする必要があることは明らかです。
ファイルを読むときなどの選択肢がある場合は、「ブロッキングコールによってエンドユーザーが不当な時間を待つことになりますか?」と尋ねてください。アプリケーションの起動時には、コードは一度だけ実行され、エンドユーザーはサーバーに触れる機会がないため、答えは一般的に「いいえ」です。しかし、Webリクエストに応答している場合は、すべてのユーザーがアウトバウンドAPI呼び出しを待機するか、ディスク読み取りがすべてのユーザーのサイト速度を低下させますが、ノンブロッキング呼び出しではノードが新しいリクエストを処理し続けます要求が戻ってきます。
2つの数字を追加してもCPUがブロックされて実行されるわけではないので、どちらの例もノンブロッキング(通常の定義による)です。 I/O操作は通常実行します。 – rob