9.4 コールバック関数とコールバック地獄
以前の JavaScript では、非同期処理が終わった後にやりたいことを、引数として渡す小さな関数(コールバック関数)の中に書いていました。
しかし、複数の非同期処理を順番に行おうとすると、関数の中にさらに関数を書くことになり、ネスト(入れ子構造)が深くなることで、コードが非常に読みづらくなってしまいます。
この状態をコールバック地獄や破滅のピラミッドと揶揄していました。
9.4.1 コールバック地獄の例を実行するプログラム
setTimeout 命令を使って、コールバック地獄を実現してみます。
ソースフォルダ:public/ch09
ファイル名:callback-hell.js
➢ callback-hell.html
前の項で作った ch09/delay.html をコピーし、ch09 にペーストしてください。
その際に、ファイル名を callback-hell.html に変更します。
ファイル内の delay.html や delay.js の記述も、callback-hell.html や callback-hell.js に修正します。
➢ callback-hell.js
// callback-hell.js
// 1秒ごとに順番にメッセージを出したい場合
setTimeout(() => {
alert("1秒経過:ステップ1");
setTimeout(() => {
alert("さらに1秒経過:ステップ2");
setTimeout(() => {
alert("加えて1秒経過:ステップ3");
// これ以上続くと、右側へどんどんズレていき、解読不能になります...
}, 1000);
}, 1000);
}, 1000);
実行結果


解説
ソースコードの構造とコメントが全てです。
このサンプルプログラムは、メッセージを表示しているだけですが、より複雑な処理をコールバック関数内部に記述した状態で、ネスト(入れ子構造)が深くなると、コードの可読性が落ちることは想像に難くありません。
カッコ { } が何重にも重なり、どこで処理が区切られているのか一目で分からなくなります。これが、多くの開発者を悩ませた「地獄」の正体です。
現代の JavaScript では、この問題を解決するために Promise や async/await という新しい書き方が導入されました。これらについては次章で詳しく学んでいきましょう。
