2

私がこれを理解するのを手伝ってください。

いくつかのメソッドを呼び出す関数があります。

function() {
   methodA(function(){...});
   methodB();
   methodC();
}

コールバックや無名関数を持たない言語から、メソッドが戻るまで実行が続行されないという事実に慣れました。

そのため、コールバックを使用してmethodAを呼び出した場合、実行はメソッドが返されるまで待機する必要がありますが、これは非同期ではありませんよね?

たとえば、あるオブジェクトへのコールバックを保存して、methodAを返すことができるようにします。次に、methodBとmethodCが実行されます。そして、ユーザーがボタンをクリックすると、一部のハンドラーがコールバックを実行しますか?

私は、javaまたはpythonと比較してjavascriptについて非同期ではないという結論に達しました(マルチスレッドに関してではありません)... javaでは、コールバックはクロージャ/匿名メソッドではなく、「execute」メソッドを持つオブジェクトであるためです。まったく同じですが、もう少し複雑です...もちろん、DOMに固有のこのJSイベントシステムがあります

4

3 に答える 3

5

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 で期待どおりに機能します。

于 2011-05-21T20:04:02.127 に答える
1
function main() {
   methodA(function callback(){...});
   methodB();
   methodC();
}

コールバックがすぐに実行されないと仮定します。

実行順序:

  • 方法A
  • 方法B
  • メソッドC
  • ...スタックが空になるまで他のこと
  • 折り返し電話
于 2011-05-21T20:02:18.767 に答える
0

setIntervalJavascript は、 、setTimeout、またはコールバックまたは を使用してサーバーにリクエストを行う場合を除き、シーケンシャルですonload。他のケースがあるかどうかはわかりません。

次のようなものがある場合:

function methodA(fn){
  ...
  fn();
}

次に、呼び出し時にコールバックが呼び出されますmethodA(function(){...})

于 2011-05-21T20:07:08.457 に答える