こんにちは、ライターのマサトです!
今回は、特定の処理を意図したタイミングで実行できるコールバックについて学習をしていきましょう。ある処理を実行したらこちらの処理を実行する…みたいなフローの制御が行えるようになります。
この記事では、
- 「コールバック」とは?
- 「コールバック」の使い方
- 「Ajax」でコールバックを使う
- 「bind」でコールバックに引数を使う
という基本的な内容から、応用的な使い方に関しても解説していきます。この記事で、コールバックをしっかり学習して自分のスキルアップを目指しましょう!
「コールバック」とは?
それでは、まず最初に「コールバック」の基本的な知識から学習を進めていきましょう。「コールバック」は、簡単に言うと関数の引数に別の関数を指定する処理を指します。
これにより、Aという関数が実行されたあとに引数で指定していたBという関数を実行するということが可能になります。よく使われるケースとして、例えばサーバーからデータを取得したあとに次の処理を実行したいという場合です。
サーバーへのアクセスは時間が掛かるため、処理を待たないで実行すると不具合の原因にも繋がります。本記事では、コールバックの基本から応用まで学習できるように構成しているのでぜひ参考にしてみてください!
「コールバック」の使い方
この章では、コールバックの基本的な書き方や使い方について学習をしていきましょう。一般的な構文や実際のプログラミング手法、即時関数の活用について学んでいきます。
コールバックの構文と書き方について
まずは、もっとも基本となる構文から見ていきましょう!
と言っても、方法は簡単で一般的な関数の引数に別の関数を指定して実行するだけです。
function 関数( 別の関数(callbck) ) { //何らかの処理を記述する //引数に指定した関数を実行する callback(); }
このように、通常の関数を記述する感覚で処理を実行していきます。少し違うのは、引数に指定しているのが関数なので処理の最後にその関数を実行する記述をする点です。
これにより、関数が実行されたあとに引数で指定した関数が順番に実行するようになるわけです。
基本的なコールバックの実行方法
それでは、実際のプログラミング手法を見てみましょう。コールバックの処理が分かりやすいように「setTimeout()」を使ってわざと時間の掛かる処理を作ってみます。
function testFunc(callback) { setTimeout(function() { console.log('testFuncが実行されました'); callback(); }, 2000) }
この例では、「testFunc()」という関数を作ってわざと2秒の時間を要する処理を記述しています。引数には「callback」と記述していますが名称は何でも構いません。重要なのは、処理の最後に引数で指定した関数を実行するということです。
次に、引数で指定する関数を以下のように作ります。
function myCallback() { console.log('myCallbackが実行されました'); }
これは単純な文字列をコンソールログへ出力するだけの簡単な関数ですね。
そして、コールバックを使って処理を実行するには次のように記述します!
testFunc(myCallback);
実行結果
testFuncが実行されました myCallbackが実行されました
最初に作成した「testFunc()」の引数に関数を指定しているのが分かりますね。「testFunc()」は2秒掛かる処理を行ってから「myCallback()」関数をコールバックして実行します。実行結果を見ると順番に関数が実行されているのが分かりますね!
即時関数(無名関数)を使ったコールバックの作り方
先ほどは、関数の引数に別の関数を指定すると解説しました。
しかしながら、単純な処理であれば即時関数(無名関数)を使った方が効率が良いこともあります。もう一度、コールバックの記述を見てみましょう!
testFunc(myCallback);
コールバック処理を記述した関数の引数に、別の関数を指定していますね。
これを即時関数に置き換えると次のようになります。
testFunc(function() { console.log('即時関数が実行されました'); })
実行結果
testFuncが実行されました 即時関数が実行されました
引数へ関数を直接記述していますね。このようにしても実行結果は同じで、順番通りに関数が実行されているのが分かります。
「Ajax」でコールバックを使う
この章では、「Ajax」通信によるコールバックの使い方について見ていきましょう。主に、Ajaxの基本と実際のコールバック処理について学んでいきます。
Ajaxの基本的な使い方について
まずは、Ajaxの基本についておさらいをしておきましょう。Ajax通信を行うと非同期処理が可能になり、処理の結果を待たなくても次の処理が行えるようになります。例えば、サーバーから何らかのデータを取得する場合、結果が返ってくるまで待つ必要がないわけです。
一般的にJavaScriptでAjax通信を実現するには、「XMLHttpRequest()」を利用します!
const xhr = new XMLHttpRequest(); xhr.open('GET', '/sample.json'); xhr.send(); xhr.onreadystatechange = function() { if(xhr.readyState === 4 && xhr.status === 200) { //ここに処理を記述する } }
この例では、サーバーから「sample.json」というファイルを非同期で取得する処理を行っています。最終的に取得したデータを利用して処理を記述するのが一般的です。Ajax通信についてまだよく分からない方は、次の記事で体系的にまとめているのでぜひ参考にしてみてください!
Ajaxでコールバックを使ったデータ取得方法
それでは、実際にAjax通信を使ったコールバックを作成してみましょう。まずは、先ほど作成したAjaxのプログラムを関数内に記述していきます。
function getJsonData(callback) { const xhr = new XMLHttpRequest(); xhr.open('GET', '/sample.json'); xhr.send(); xhr.onreadystatechange = function() { if(xhr.readyState === 4 && xhr.status === 200) { callback(JSON.parse(xhr.responseText)); } } }
この例では、「getJsonData()」という関数内にAjaxの処理を記述しています。この関数はコールバックを使うので、引数に別の関数を指定するように記述しているのがポイントです。
そして、サーバーから取得したデータをコールバック関数に設定しているのが分かりますね。次にコールバック関数を作ってみましょう!
function getUserName(json) { console.log(json.users[0].name); }
取得したデータから「name」プロパティだけを抽出してコンソールログへ出力しています。そして、次のように記述することでコールバックは実行されます!
getJsonData(getUserName);
まず最初に「getJsonData()」が実行されてサーバーからデータを取得します。そのあとに、「getUserName()」を実行してnameプロパティだけを抽出してコンソールに出力するという流れです。
「bind」でコールバックに引数を使う
この章では、「bind」を活用したコールバック処理について見ていきましょう。主に、bindの基本とコールバックに引数を設定する方法について学んでいきます。
bindの基本的な使い方について
まずは、bindの使い方について見ていきましょう。「bind」は、対象となる関数の「this」を変更(固定化)したり、新しく引数を設定することができるメソッドになります。
例えば、次のような関数があるとします。
function sample() { console.log(this); }
これは、単純にthisの値を返すだけなので結果は「windowオブジェクト」が出力されます。これをbindを使ってthisの値を変更するには次のように記述します。
const result = sample.bind('これがthisです'); result();
bindの引数に注目してください。文字列が指定されていますが、実行するとwindowオブジェクトではなく設定した文字列が出力されます。つまり、thisの値を任意のデータに変更できるわけです。
さらに、引数を設定することも可能です。
function sample(value) { console.log(value * value); } const result = sample.bind(null, 10); result();
こちらもbindの引数に注目してください。今回はthisの値を変更しないので第1引数はnullにして、第2引数に「10」を設定しています。これにより、sample関数の引数へ「10」が設定されるというわけです。
bindでコールバックに引数を設定する方法
bindの基本が分かったところで、実際にコールバックへ組み込んでみましょう!
まずは次のようなコールバック処理を見てください!
function testFunc(callback) { console.log('testFuncが実行されました'); callback(); } function myCallback(name) { console.log('こんにちは、' + name + 'さん!'); } testFunc(myCallback);
この例では、「myCallback()」の引数に「name」が設定されているという点に注目してください。このまま実行すると「name」の部分が何も指定されていないので「undefined」になってしまいます。
このようなケースで、あとから引数に何らかの値を設定するにはbindが便利です。
testFunc(myCallback.bind(null, '太郎'));
実行結果
testFuncが実行されました こんにちは、太郎さん!
この例では「myCallback()」にbindを使って引数を設定しているのが分かります。これにより、実行結果のようにコールバック関数の引数へ任意の値を指定できるわけです。
まとめ
今回は、関数の引数に別の関数を指定して処理を制御できる「コールバック」について学習をしました。
最後に、もう一度ポイントをおさらいしておきましょう!
- コールバックは通常の関数に別の関数を実行する処理を記述する
- コールバックを使うと意図的に処理の順番を制御して実行できる
- bindを使うとコールバック関数へ任意の値を引数に設定できる
上記内容を踏まえて、ぜひ自分でもプログラミングに取り入れて活用できるように頑張りましょう!