JavaScript のコールバックは、暗黙的に非同期動作を追加しません。コールバック関数が呼び出されると、通常の関数と同様にすぐに実行されます。(実際には、コールバック関数は単なる通常の関数です...)
このため、この例のコールバックの実行が他のメソッドとの関係でいつ実行されるかを判断することは不可能です (呼び出される前に実行できないことを除いて)methodA。後で、またはまったくありません。(ただし、例外がない限り、または関数の 1 つが他の関数の 1 つを呼び出す場合を除き、が実行される前に実行され、その前に実行されます。例外がスローされた場合は、どちらも呼び出されません)。methodAmethodBmethodAmethodBmethodCmethodAmethodBmethodC
非同期動作を追加するのは、タイマー イベントやボタン クリックなどの UI アクションなどの非同期イベントソースです。
ただし、Javascript にはスレッドがないか、サポートされていないことに注意してください。新しい非同期イベントをトリガーする前に、Javascript を「停止」する必要があります (実行は、非同期イベント ソースから呼び出されたコールバック関数から戻る必要があります)。(非同期イベントは [必要に応じて] キューに入れられるため、別のコールバックの実行に時間がかかりすぎてもタイマー イベントが「失われる」ことはありません。)
これが、while (true) {}がブラウザ ページをフリーズさせ、ボタン イベント ハンドラが処理されないようにする理由です。
ハッピーコーディング。
例 ( jsfiddle demo ):
function invokeNow(callback) {
// nothing asynchronous going on here.
// the callback is invoked right now and the result is returned.
return callback()
}
alert(invokeNow(function () { return "Hello world!" }))
function doLater(callback) {
// setup an asynchronous event
setTimeout(callback, 1000)
return "It isn't 'later' yet!"
}
alert(doLater(function () {
alert("Later!")
// note that this is running in the callback from the previous
// timer event. if this code was below the outer alert then
// it wouldn't have allowed the first timer callback to have occurred
// until the blocking while was complete
alert(doLater(function () { alert("I still ran!") }))
var end = (+new Date) + 4000
while ((+new Date) < end) { /* wait */ }
alert("I am done waiting")
}))
警告: Firefox 4 (4.0.1) と上記のコードに問題があるようです。示されているように動作しますが、タイムアウトが約 800 ミリ秒未満の場合、予想される順序は実際の順序とは異なります。SO: Asynchronous timer event running synchronously (“buggy”) in Firefox 4?を投稿しました。うまくいけば、いくつかの解決策があるでしょう。この動作は、Firefox 3、IE 9、および Chrome 11 で期待どおりに機能します。