コールバック関数


4-1コールバック関数とは?


コールバック関数(callback function)は、他のコードパラメータに渡される関数です.
callback=call(コール、コール)+back(戻る、戻る)
コールバック関数を受信したコードは、必要に応じて適切な時間にこのコールバック関数を実行します.
関数Xが呼び出されると、「特定の条件で関数Yを実行して通知してください」という要求が同時に発行されます.
コールバック関数は制御権に深く関連しています.
コールバック関数は、パラメータとして別のコード(関数またはメソッド)に渡され、その制御権を別の関数に委任します.

4-2制御権

// 예제 4-2 콜백 함수 예제(1-2) setInterval
var count = 0;
var cbFunc = function () {
	console.log(count);
	if(++count > 4) clearInterval(timer);
};
var timer = setInterval(cbFunc, 300);

// -- 실행 결과 --
// 0  (0.3초)
// 1  (0.6초)
// 2  (0.9초)
// 3  (1.2초)
// 4  (1.5초)
timer変数は、setIntervalのID値を含む.setIntervalに渡される最初のパラメータcbFunc関数(この関数はコールバック関数)は、0.3秒ごとに自動的に実行される.
コールバック関数の内部では、countの値が出力され、countの値が1増加し、4より大きいと繰り返し実行が終了します.
setIntervalと呼ばれる「その他のコード」が最初のパラメータとしてcbFunc関数を渡すと、渡されたsetIntervalは、自分の判断に従って適切な時間(0.3秒毎)に匿名関数を実行する.
コールバック関数の制御権を受け入れるコードには、コールバック関数呼び出し点の制御権があります.

コールバック関数がmapメソッドの場合


「目覚まし時計の針を所望の時刻に向けて設定し、目覚まし時計のスイッチをONにする」というルールに従う必要があります.同様に、mapメソッドを呼び出して必要な配列を取得するには、mapメソッドで定義されたルールに基づいて関数を記述する必要があります.このルールには、コールバック関数パラメータとして使用する値とその順序も含まれます.

this


「コールバック関数も関数なので、デフォルトではグローバルオブジェクトを参照しますが、制御を受け入れるコードでコールバック関数に別のターゲットを指定すると、そのターゲットが参照されます.」thisが他の値を含むのは、制御権を受け入れるコードでcall/applyメソッドの最初のパラメータにcallback関数内部のthisオブジェクトを明示的にバインドするためである.
01 setTimeout(function () { console.log(this); }, 300); //(1) Window { ... }
02
03 [1, 2, 3, 4, 5].forEach(function (x) {
04     console.log(this);                               //(2) Window { ... }
05 });
06
07 document.body.innerHTML += '<button id="a">클릭</button>';
08 document.body.querySelector('#a')
09     .addEventListener('click', function (e) {
10     console.log(this, e);                            //(3)<button id="a">클릭</button>
11   }                                             // MouseEvent { isTrusted: true, ... }
12 );
(1)のsettimeoutは内部コールバック関数を呼び出すときに呼び出しメソッドの最初のパラメータにグローバルオブジェクトを渡すので、コールバック関数のthisはグローバルオブジェクトである
(2)のforEachは単独のパラメータとしてグローバルオブジェクトに渡さなかった.
(3)のaddEventListenerメソッドのthisであるため、thisはaddEventListenerを呼び出す本体HTML Ellyを指す

4-3コールバック関数は関数です


コールバック関数を使用してオブジェクトを渡すメソッドでも、メソッドではなく関数として呼び出されます.
01 var obj = {
02 	vals: [1, 2, 3],
03 	logValues: function(v, i) {
04 		console.log(this, v, i);
05 	  }
06 };
07 obj.logValues(1, 2);               // { vals: [1, 2,  3], logValues: f } 1 2
08 [4, 5, 6].forEach(obj.logValues);  // Window { ... } 4 0
09                                    // Window { ... } 5 1
10                                    // Window { ... } 6 2
objオブジェクトのlogValuesをメソッドとして定義します.7行目では、メソッド名の前にポイントがあるため、メソッドが呼び出されます.したがって、thisobjを指し、出力は因子に変換された1,2を指す.
8行目は、メソッドをforEach関数のコールバック関数に渡します.objthisであることを直接伝達する方法ではなく、obj.logValuesが指す関数のみを伝達する.
objとは直接的なつながりはありません.forEachコールバックによって関数として呼び出され、関数内部のthisはグローバルオブジェクトを表示します.
どの関数のパラメータに異なるメソッドを渡しても、これは最終的にはメソッドではなく関数にすぎません.

別の値を4-4コールバック関数のthisにバインド


コールバック関数でこのオブジェクトを表示したい場合は?


このパラメータを個別のパラメータとして受信する関数では、必要な値を渡すだけです.
そうでなければ、thisの制御権も譲渡され、ユーザーは勝手に値を変更することはできません.
従来、thisを他の変数に含めてコールバック関数として使用する関数は、通常、thisではなくthisを使用し、モジュールとして使用します.

4-5コール地獄と非同期制御


コールバック地獄(callback hell):コールバック関数を匿名関数に渡すプロセスを繰り返し、コードのインデントレベルが耐えられなくなります.
主にイベント処理やサーバ通信などの非同期タスクを実行するために、このような形式が頻繁に発生します.可読性が悪く、コードの修正も難しい.
非同期
≪同期コード|Synchronize Code|oem_src≫:現在実行中のコードが完了した後、次のコードを実行します.
  • CPU計算即時処理可能な大部分のコード
  • 計算は複雑で、CPUが計算に多くの時間を必要としても、
  • 非同期コード:現在実行中のコードが完了しているかどうかにかかわらず、すぐに次のコードに移動します.
  • ユーザは、特定の時間までに実行を一時停止するように要求する
  • .
  • ユーザ直接介入時に実行(addEventListener)
  • Webブラウザ自体ではなく別のターゲットに何かを要求し、応答時に関数(XMLHttpRequest)
  • を実行する
  • 要求、実行待ち、処理待ち
  • 現代のjavascriptでは、Webの複雑な勘定科目、非同期コードの比重勘定科目をサポートしています.
    それと同時に、callback地獄に陥りやすい.
    JavaScript陣営は、一連の非同期タスクを同期または同期させるように努力してきた.
    ES 6導入PromiseGenerator、ES 2017導入async/await
     var addCoffee = function (name) {
    	return new Promise(function (resolve) {
    		setTimeout(function () {
    			resolve(name);
    		}, 500);
    	});
    };
    var coffeeMaker = async function () {
    	var coffeeList = '';
    	var _addCoffee = async function (name) {
    		coffeeList += (coffeeList ? ',' : '') + await addCoffee(name);
    	};
    	await _addCoffee('에스프레소');
    	console.log(coffeeList);
    	await _addCoffee('아메리카노');
    	console.log(coffeeList);
    	await _addCoffee('카페모카');
    	console.log(coffeeList);
    	await _addCoffee('카페라떼');
    	console.log(coffeeList);
    };
    coffeeMaker();
    非同期動作を実行する関数の前に、asyncとマークされます.
    関数内部では、実際の非同期操作が必要な位置フラグawaitであれば、後のコンテンツをPromiseに自動的に変換し、そのコンテンツがresolveであれば次のステップに進むことができる.Promiseに類似したthenの効果が得られる.