概要
JavaScriptを学習、理解を深めるため「JavaScript Primer 迷わないための入門書」を読み、
理解した内容等を記載していく。
「【JavaScript】JavaScript入門一覧」に他の記事をまとめています。
この記事で理解できること
- コールバック関数を用いた非同期処理
- コールバック関数を用いた非同期処理における例外処理の方法
コールバック関数を用いた非同期処理
- ある非同期処理を行う関数などに、非同期処理が完了したタイミングで実行する関数(コールバック関数)を登録しておく。
- 非同期処理の中で、さらに非同期処理を行いたい場合は、コールバックをネストすることで実行可能。
/** 定義 */
// 非同期処理を行う関数を定義(今回はsetTimeout関数で処理が2秒かかる想定で実行)
function asyncFunc(result, callback) {
console.log("非同期処理を開始します");
setTimeout(() => {
const result = true; // 色々と処理を経て取得した結果の想定
// 登録されたコールバックを呼び出す
callback(result);
}, 2000);
}
/** 実行 */
console.log("同期処理1");
// 非同期処理(関数)を実行
// 第2引数に渡している(result)..から始まる部分がコールバック関数(アロー関数形式)を登録している(渡している)部分
asyncFunc(true, (result) => {
if (result) {
console.log(`結果は${result}か。よし後続の処理を行うぞ...`);
} else {
console.log(`非同期処理が失敗しました`);
}
});
console.log("同期処理2");
console.log("同期処理3");
// => 同期処理1
// => 非同期処理を開始します
// => 同期処理2
// => 同期処理3
// => (非同期処理開始2秒後..)結果はtrueか。よし後続の処理を行うぞ...
エラーファーストコールバック
- ES2015より前までは、
非同期処理中に発生した例外を扱う方法
として広く使われていた。 - エラーファーストコールバックとは、次のような非同期処理におけるコールバック関数の呼び出し方を決めたルール
- 処理が失敗した場合
- コールバック関数の第一引数に
エラーオブジェクト
を渡して呼び出す。
- コールバック関数の第一引数に
- 処理が成功した場合
- コールバック関数の第一引数には
null
を渡し、第二引数に成功時の結果
を渡して呼び出す。
- コールバック関数の第一引数には
- 処理が失敗した場合
- 非同期処理における
エラーハンドリングの書き方を決めたルール
であって仕様ではない。
function errorFirstCallBack(result, callback) {
setTimeout(() => {
// resultは何らかの処理の結果(今回は直接bool値を渡し条件分岐している)
if (result) {
// 成功の場合、コールバック関数の第一引数はnull、第二引数に結果としてオブジェクトを指定
callback(null, {result: result});
} else {
// 失敗の場合、コールバック関数の第一引数はエラーの内容を指定
callback(new Error("エラーが発生しました"))
}
}, 1000);
}
// 非同期処理が成功した想定の処理
errorFirstCallBack(true, (error, response) => {
if (error) {
console.log(error.message);
} else {
console.log(response);
}
})
// => { result: true }
// 非同期処理中にエラーが発生した想定の処理
errorFirstCallBack(false, (error, response) => {
if (error) {
console.log(error.message);
} else {
console.log(response);
}
})
// => エラーが発生しました
前述の通りエラーハンドリングの書き方を決めたルール
であって仕様ではないため、それっぽい書き方をしても問題になるわけではない。
function errorFirstCallBack(result, reject, response) {
setTimeout(() => {
// resultは何らかの処理の結果(今回は直接bool値を渡し条件分岐している)
if (result) {
// 成功の場合、コールバック関数の第一引数はnull、第二引数に結果としてオブジェクトを指定
response({result: result});
} else {
// 失敗の場合、コールバック関数の第一引数はエラーの内容を指定
reject(new Error("エラーが発生しました"))
}
}, 1000);
}
function rejectFunc(error) {
console.log(error.message);
}
function successFunc(result) {
console.log(result);
}
// 成功した想定の処理
errorFirstCallBack(true, rejectFunc, successFunc); // => { result: true }