コールバック関数とは
function hello(name) {
alert(`Hello, ${name}`);
}
function processUserInput(callback) {
const name = prompt("Please enter your name.");
callback(name);
}
processUserInput(hello);
- 上記Cブロックのソースで
callback = hello
を行い、
callbackオブジェクトにhelloメソッドの参照情報が格納される
- C#のデリゲート、Cの関数ポインタに近い動き
- 下記ソースのようにgoodbyeメソッドを追加し
processUserInput(goodbye);
とすれば、
アラートで出力されるのはDブロックのソース内容となる
function goodbye(name) {
alert(`Goodbye, ${name}`);
}
- 以下の動きからコールバック関数は自身が何か実行しているわけではなく
引数で受け取ったメソッドの情報を、展開先の処理内に横流ししているだけ。
- なので少し話はそれるが、コールバックを引数に持つブロックBのメソッドは
多数のイベントハンドラを受付け、発火させるという実装でもできそう
コールバックを使用する例:非同期処理
- 上記のA-Dブロックを非同期で実行させたいとなるとコールバックのネストか
async,awaitのどちらか
- 前者は非同期の処理数に応じてネストが入れ子になるコールバック地獄になるので後者で実装する
function hello(name) {
return new Promise(resolve => {
alert(`Hello, ${name}`);
resolve(name);
})
}
function goodbye(name) {
return new Promise(resolve => {
alert(`Goodbye, ${name}`);
resolve(name);
})
}
async function processUserInput(callback) {
const name = prompt("Please enter your name.");
return await hello(name).then(goodbye);
}
processUserInput();
- goodbyeメソッドを追加したことによって非同期処理が必要になるようにした
- processUserInputメソッドを下記のように書くと同期処理は担保されない
hello(name)
goodbye(name);
- async,awaitによりコールバックのネストは回避されたが、
Promiseクラス、thenメソッドの引数にはコールバックは使用されている
- 立ち位置は同じで受け取ったメソッドの情報の参照をアロー関数以降の処理に横流ししているだけ
まとめ
- async,awaitでもコールバック関数は使用している
- あくまでコールバックの「ネスト」が解決するだけ