JavaScript入門 練習問題 5:非同期処理とコールバック関数の実行順序
JavaScriptのコールバック関数と非同期処理について、以下のコードを実行したときのコンソールへの出力として正しいものを選んでください。
```javascript
function processMessage(message, callback) {
console.log('1. メッセージ処理開始: ' + message);
// 非同期処理をシミュレート
setTimeout(function() {
console.log('4. 非同期処理完了: ' + message);
callback(message + ' 処理済み');
}, 0);
console.log('2. メッセージ処理関数終了');
}
function showResult(result) {
console.log('5. 結果: ' + result);
}
console.log('0. プログラム開始');
processMessage('データ', showResult);
console.log('3. メインプログラム継続');
console.log('6. プログラム終了');
```
- 0. プログラム開始 1. メッセージ処理開始: データ 2. メッセージ処理関数終了 3. メインプログラム継続 4. 非同期処理完了: データ 5. 結果: データ 処理済み 6. プログラム終了
- 0. プログラム開始 1. メッセージ処理開始: データ 2. メッセージ処理関数終了 3. メインプログラム継続 6. プログラム終了 4. 非同期処理完了: データ 5. 結果: データ 処理済み
- 0. プログラム開始 1. メッセージ処理開始: データ 4. 非同期処理完了: データ 5. 結果: データ 処理済み 2. メッセージ処理関数終了 3. メインプログラム継続 6. プログラム終了
- 0. プログラム開始 1. メッセージ処理開始: データ 2. メッセージ処理関数終了 4. 非同期処理完了: データ 5. 結果: データ 処理済み 3. メインプログラム継続 6. プログラム終了
- 0. プログラム開始 1. メッセージ処理開始: データ 3. メインプログラム継続 2. メッセージ処理関数終了 6. プログラム終了 4. 非同期処理完了: データ 5. 結果: データ 処理済み
Qraftユーザーの成績:正答率 43%(6/14回正解)
正解と解説を見る
JavaScriptはシングルスレッドで動作し、`setTimeout` の処理は同期処理がすべて終わってからイベントループで実行されます。そのため出力順は「0→1→2→3→6→4→5」になります。
【正解の理由】
メインプログラムの同期処理(0, 1, 2, 3, 6)がすべて完了してから、`setTimeout` に登録された非同期処理(4, 5)がイベントループで実行されます。`setTimeout(fn, 0)` は「0ミリ秒後に即実行」ではなく「現在の同期処理が終わってから実行」という意味です。
【不正解の理由】
• 0→1→2→3→4→5→6:非同期処理(4, 5)が同期処理の「6. プログラム終了」より前に実行されるはずがありません。
• 0→1→4→5→2→3→6:非同期処理が「2. メッセージ処理関数終了」より前に割り込むことはなく、同期処理が先にすべて完了します。
• 0→1→2→4→5→3→6:「3. メインプログラム継続」も同期処理なので、非同期処理(4, 5)より先に実行されます。
• 0→1→3→2→6→4→5:`processMessage` 関数内では「1→2」の順に同期実行されてから関数を抜けるため、2は3より前に出力されます。