asyncシリーズ:コールバック


導入


JavaScriptの初心者に最も悪名高いgotchasの一つは、非同期プログラミングのアイデアです.このシリーズはすべてJavaScriptのasyncを解読することです.

asyncはどういう意味ですか?


我々が書くコードの大部分は、連続的に、または、同期的に実行します.これは実行行1で、2行目の3行目です.
例えば、以下の全ての同期機能呼び出しがある.あなたは一度にそれらのいずれかを行うことができます.あなたがシャワーをしている場合は、安全に目を覚ますタスクを完了することができます完全に完了している.
wakeup()
eatBreakfast()
takeShower()
しかし、JavaScriptではいくつかの関数呼び出しが同時に実行されます.これはブラウザが実際にそれらの間を切り替えるので、同時に進行するように見えます.
たとえば:朝から目を覚ます瞬間から、あなたが見始める.その後、また、移動を開始することがありますいくつかのポイントでは、食べることになる.あなたも一度にすべての3つを行う可能性があります!注意:あなたが食べ始める前にあなたが見始めたとしても、食べる仕事は見ている前に完了します.これは本質的に、非同期関数呼び出しがどのように動作するかです.
see()
move()
eat()
このため、一連の非同期ファンクションコールは、開始したときとは異なる順序で実行を終了します.多くの場合、特定の順序が望まれるとき、これは新しいプログラマーへの欲求不満のポイントでありえます.

なぜ、これは起こりますか?


それが難しい要件でない間、あなたが最初の場所でなぜ起こるかについての感謝を得たいと思うならばJavaScriptランタイムで私のポストを見ることができます.


非同期コード


私は3つの非同期関数printblue/green/redを持っています.それらはすべて同時実行されるが、それぞれ異なる実行時間を持つ.グリーンは、それから赤、それから最も速いです.それで、彼らがこれのように呼ばれるならば.
printBlue("Blue");
printGreen("Green");
printRed("Red");
出力:

出力は:緑、赤、青.下の図は、これらの関数のタイミングを視覚化します.

流れ始める


それらの個々の実行速度のために、機能は彼らが「緑」、「赤」と「青い」を印刷していると呼ばれていたと呼ばれていたより異なった順序で終わりました.
プログラミングでcontrol flow ステートメントの実行順序を強制する概念です.JavaScriptでは、開発者にこれを達成する能力を与える1つの方法は、コールバック関数を受け入れる非同期関数を持つことです.
コールバック関数は関数cであり、他の関数a(しばしばasync)に渡される.
AはAとも言われるhigher-order 関数はパラメータとして別の関数を持っていることに起因します.
幸運にも、我々の印刷機能はコールバック関数を受け入れます.その後、コールバックとしてヘルパー関数を渡します.
//helper function 1
function doPrintRed(){
  //calls print red with our desired parameter
  printRed('Red');
}

//helper function 2
function doPrintGreenRed(){
  //calls printGreen with our desired parameter 
  //then passes doPrintRed as a callback
  printGreen('Green', doPrintRed);
}

//call printBlue then passes do doPrintGreenRed as a callback
printBlue("Blue", doPrintGreenRed);
しかし、これは不必要に長いです.コールバックとして渡す以外にヘルパー関数を使用しないので、代わりに匿名関数を使用できます.
匿名関数は、関数を参照することができる任意の場所に書き込むことができる無名関数定義です.例えば、doprintredを書く代わりに、doprintgreenに無名関数を提供することができます.
//helper function 2
function doPrintGreenRed(){
  //calls printGreen with our desired parameter 
  //replace reference to doPrintRed with an anonymous function
  printGreen('Green', function(){
      //calls print red with our desired parameter
      printRed('Red');
  });
}

//call printBlue then passes do doPrintGreenRed as a callback
printBlue("Blue", doPrintGreenRed);

doprintredのコードを匿名関数に移動し、コールバックとしてprintgreenに渡しました.したがって、printgreenの2番目のパラメータは匿名コールバック関数と呼ばれます.
その後、以下を達成するために、doprintgreenredのためにプロセスを繰り返すことができます.
//replace reference to doPrintGreenRed with an anonymous function
printBlue("Blue", function(){
   //calls printGreen with our desired parameter 
   printGreen("Green", function(){
     //calls print red with our desired parameter
     printRed("Red");
   });
});
printblue ()で渡されるコールバック関数はprintgreen ()を呼び出します.printgreen ()もコールバック関数を受け取ります.printblue/green/redは、受信したコールバックが画面に印刷された後のみ実行されるように設計されています.
これが出力です.

実行は現在このようになります.

これは、最も外側の関数が実行する外部関数で待機しなければならず、外部関数が実行を開始するために別の外部関数を待機しなければならないためです.

高次関数の記述


コールバックを受け入れる関数を設計するための非同期関数の作成者であり、適切な値でコールバックを実行し、ドキュメントを使って説明します.
コールバック関数を受け取る高次のadd関数の簡単な実装です.
function add(a, b, callback){//allow a callback to be passed
  let answer = a + b;//perform calculation
  callback(answer);//pass the output of the calculation to the callback
}

add(4, 5, function(result){
 console.log("The result is", result);
});//Output: The result is 9

関数add ()はsumを計算し、結果をadd ()に渡した関数パラメータに渡します.add ()のような高次関数は結果を返さず、代わりに結果を渡す関数を求めます.
この例ではコードが利用可能ですREPL だからあなた自身を試してみることができます.

結論


そして、それは非同期のJavaScriptへのイントロを終えます.多くのJavaScript APIはfetch ()を含む非同期です.この基本的な概念でグリップになるあなたの旅によく役立つ.