Wie wird Javascript-Code bei der Verwendung von Rückrufen asynchron?

26

Ich habe viel online gelesen und versucht, herauszufinden, wie man asynchronen JavaScript-Code schreibt. Eine der Techniken, die in meiner Forschung häufig zum Einsatz gekommen sind, ist die Verwendung von Rückrufen. Ich verstehe zwar, wie eine Rückruffunktion geschrieben und ausgeführt wird, bin aber verwirrt, warum Rückrufe die JavaScript-Ausführung scheinbar automatisch asynchron machen. Meine Frage lautet also: Wie bewirkt das Hinzufügen von Rückruffunktionen zu meinem JavaScript-Code, dass der Code automatisch asynchronisiert wird?

Zach Dziura
quelle
2
Es könnte Sie interessieren, wie der Browser dies in einem einzigen Thread erreicht, der von John Resig geschrieben wurde: ejohn.org/blog/how-javascript-timers-work
Jalayn
@Jalayn. Vielen Dank. Ihr Kommentar machte den Unterschied, nachdem Sie die verschiedenen Antworten gelesen hatten.
Kushalvm

Antworten:

26

Das tut es nicht. Nur einen Rückruf entgegennehmen oder einen Rückruf weiterleiten heißt nicht, dass er asynchron ist.

Beispielsweise nimmt die .forEachFunktion einen Rückruf entgegen, ist jedoch synchron.

var available = false;
[1,2,3].forEach( function(){
    available = true;
});
//code here runs after the whole .forEach has run,
//so available === true here

Der setTimeoutnimmt auch einen Rückruf entgegen und ist asynchron.

function myFunction( fn ) {
    setTimeout( function() {
        fn(1,2,3);
    }, 0 );
}

var available = false;
myFunction( function() {
    available = true;
});
//available is never true here

Das Verbinden mit einem asynchronen Ereignis in Javascript erfordert immer einen Rückruf. Dies bedeutet jedoch nicht, dass das Aufrufen oder Weitergeben von Funktionen immer asynchron ist.

Esailija
quelle
2
@SteveEvers Ich denke, Sie könnten den MDN-Artikel dann bearbeiten . Rückruf ist ein sehr gebräuchlicher Begriff in Javascript für jede Funktion, die an eine andere übergeben wird und die Sie mit der von Ihnen angegebenen Funktion zurückruft. Warum kompliziert? Bearbeiten: Rückruf wird auch in Spezifikationen verwendet
Esailija
3
@SteveEvers "Rückruf impliziert Asynchronität" ist eine C # / Microsoft-Eigenheit. en.wikipedia.org/wiki/Callback_(computer_programming)
Esailija
1
@MikeBrown Ich schätze, ich habe zu viel in seinem Profil gelesen und diese - die am meisten hochgeladene Antwort gibt sicherlich eine Idee, dass "Rückrufe Asynchronität implizieren".
Esailija
1
Aber das mit @SteveEvers ist auch falsch. Rückrufe bedeuten keine Asynchronität, nur, dass jemand anderes für den "Rückruf" verantwortlich ist.
Michael Brown
1
+1, weil Steve Evers falsch liegt
slebetman
23

Das Geheimnis der "Magie" ist, dass die Ereignisse, denen Sie die Rückrufe zuweisen, asynchron sind. Sie werden "unter der Haube" implementiert, um sich darum zu kümmern, was sie tun (z. B. etwas von einem Remote-Server abrufen), und zwar außerhalb der JS-Sandbox. Und sobald sie mit ihrer Arbeit fertig sind, geben sie der JS-Engine eine Nachricht, um ein Ereignis aufzurufen. Wenn die JS-Engine mit dem fertig ist, was sie gerade tut, ruft sie alle Ereignisse auf, die in der Warteschlange stehen (oder wartet auf eine neue Nachricht), und dann wird Ihr Rückruf "magisch" asynchron aufgerufen!

( HINWEIS: Dies ist ein sehr allgemeiner, konzeptioneller Überblick über das Thema, der keine Details enthält, da verschiedene JS-Engines die Dinge auf unterschiedliche Weise implementieren. Dies ist jedoch die allgemeine Vorstellung davon, wie es funktioniert.)

Mason Wheeler
quelle
Welche Ereignisse sind das? Ein Beispiel für ein oder zwei solcher Ereignisse würde Ihre Antwort noch besser machen.
Jo Smo