Frage

bitte hilf mir das zu verstehen.

Sie haben eine Funktion, die einige Methoden aufruft:

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

Von Sprachen, die keine Callbacks oder anonymen Funktionen haben, habe ich mich daran gewöhnt, dass die Ausführung erst fortgesetzt wird, wenn eine Methode zurückkehrt.

Wenn ich also methodA mit dem Rückruf methodA , müsste die Ausführung warten, bis die Methode zurückkehrt, was nicht asynchron wäre, oder?

Damit ich zum Beispiel den Rückruf für ein Objekt speichern und die Methode zurückgeben kann.Dann werden methodB und methodC ausgeführt.Und wenn der Benutzer auf eine Schaltfläche klickt, führt ein Handler den Rückruf aus?

Ich bin zu dem Schluss gekommen, dass Javascript im Vergleich zu Java oder Python nichts Asynchrones hat (nicht in Bezug auf Multithreading)....denn in Java wäre der Callback keine closure / anonyme Methode, sondern ein Objekt mit "execute" -Methode und es wäre genau das gleiche, nur ein bisschen komplizierter...Natürlich gibt es dieses JS-Ereignissystem speziell für DOM

War es hilfreich?

Lösung

Callbacks in JavaScript fügen nicht implizit asynchrones Verhalten hinzu.Wenn eine Rückruffunktion aufgerufen wird, wird sie ausgeführt genau dann, genau wie eine normale Funktion.(Eigentlich eine Callback-Funktion is nur eine normale Funktion...)

Aus diesem Grund ist es unmöglich um festzustellen, wann die Ausführung des Rückrufs im Beispiel in Beziehung zu den anderen Methoden ausgeführt wird (außer dass er vorher nicht ausgeführt werden kann methodA aufgerufen wird) - es könnte aufgerufen werden von methodA oder methodB oder mit einem Klick später oder gar nicht.(Es sei denn, es gibt eine Ausnahme - oder eine der Funktionen ruft eine der anderen Funktionen auf - dann methodA wird vorher laufen methodB was wiederum vorher laufen wird methodC;wenn methodA warf eine Ausnahme dann auch nicht methodB noch methodC aufgerufen werden würde).

Was tun add asynchrones Verhalten ist ein asynchrone Ereignisquelle, z. B. ein Timer-Ereignis oder eine UI-Aktion, z. B. ein Klick auf eine Schaltfläche.

Es ist jedoch wichtig zu beachten, dass Javascript kein Threading hat oder unterstützt.Das Javascript muss "stoppen" (die Ausführung muss von der Rückruffunktion zurückkehren, die von einer asynchronen Ereignisquelle aufgerufen wurde), bevor ein neues asynchrones Ereignis ausgelöst werden kann.(Asynchrone Ereignisse werden [gegebenenfalls] in die Warteschlange gestellt, damit ein Timer-Ereignis nicht "verloren" geht, wenn die Ausführung eines anderen Rückrufs zu lange dauert.)

Das ist der Grund while (true) {} lässt eine Browserseite einfrieren und verhindert, dass Ereignishandler für Schaltflächen verarbeitet werden.

Viel Spaß beim Codieren.


Beispielfälle (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")
}))

Warnung:Es scheint ein Problem mit Firefox 4 (4.0.1) und dem obigen Code zu geben.Während es wie gezeigt funktioniert, weicht die erwartete Reihenfolge von der tatsächlichen Reihenfolge ab, wenn das Zeitlimit unter etwa 800 ms liegt.Ich habe gepostet SO:Asynchrones Timer-Ereignis, das synchron ausgeführt wird ("fehlerhaft") in Firefox 4? hoffentlich wird es also eine Lösung geben.Das Verhalten funktioniert wie erwartet in Firefox 3, IE 9 und Chrome 11.

Andere Tipps

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

Assuming that callback is not immediately executed.

Execution order:

  • methodA
  • methodB
  • methodC
  • ... other things until the stack is empty
  • callback

Javascript is sequential except if you use setInterval, setTimeout, or make a request to a server with a callback or using onload. Not sure there are other cases.

If you have something like:

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

Then the callback will be called when you call methodA(function(){...})

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top