Ich verstehe die Idee eines Rückrufs, bei dem ich eine Funktion in eine andere Funktion übergebe und diese Funktion dann die bereitgestellte Funktion nach Belieben verwendet.
Ich habe Mühe, zurückgestellte Rückrufe zu verstehen, auch nachdem ich sie gegoogelt habe.
Kann mir bitte jemand eine einfache Erklärung geben? Ich programmiere in Ruby, kenne C / C ++ aber vor allem war ich ein erfahrener Assembler-Programmierer. Ich frage mich also, ist es ein bisschen wie ein Stapel von Rückrufadressen, die pop'd werden? Ich hoffe, jquery oder node.js zu lernen, und diese zurückgestellten Rückrufe scheinen für beide von wesentlicher Bedeutung zu sein. Ich verstehe die grundlegenden Prinzipien des Einfädelns (obwohl ein Mutex-Objekt meinen Kopf verletzt;)
Deferred
Objekte von jQuery ? Geht es um etwas Spezielles für Node.js?Antworten:
Auf Anfrage werden hier Kommentare als Antwort präsentiert:
Ich bin mir nicht sicher, ob Sie die Tatsache völlig verstehen, dass Funktionen in JS erstklassige Objekte sind und daher erst nach ihrer Erstellung gespeichert werden können, wenn sie benötigt werden.
Angenommen, Sie möchten in eine Datei schreiben und anschließend eine Protokollmeldung ausdrucken. Sie rufen also die Funktion "write ()" (oder was auch immer) auf und übergeben ihr eine Funktion, die die Protokollnachricht ausgibt (dies ist die verzögerte Rückruffunktion). "write ()" speichert intern einen Verweis auf die angegebene Funktion, beginnt mit dem Schreiben in die Datei und richtet einen eigenen Rückruf ein, um zu erfahren, wann der Schreibvorgang abgeschlossen ist. Es kehrt dann zurück, bevor der Schreibvorgang abgeschlossen ist. Wenn dies der Fall ist, wird der interne Rückruf auf irgendeine Weise aufgerufen (dies ist die Aufgabe des zugrunde liegenden Frameworks - im Fall von node.js erfolgt dies mit einer Ereignisschleife), die dann Ihren Rückruf aufruft, der die Protokollnachricht druckt.
Der "zurückgestellte" Teil bedeutet einfach, dass Ihre Rückruffunktion nicht sofort aufgerufen wird. Aufrufen wird aufgeschoben , bis die entsprechende Zeit. Bei asynchronen Funktionen wie vielen in node.js wird der angegebene Rückruf im Allgemeinen aufgerufen, wenn die Operation abgeschlossen ist (oder ein Fehler auftritt).
Das meiste Zeug ist in node.js asynchron, aber im Browser mit zB jQuery ist das meiste Zeug tatsächlich synchron (außer natürlich für AJAX-Anfragen). Da erstklassige Funktionen in JavaScript so praktisch sind (insbesondere aufgrund der hervorragenden Schließungsunterstützung), werden Rückrufe auch überall im Browser verwendet, für synchrone Vorgänge werden sie jedoch nicht "zurückgestellt" (außer, wenn sie nicht sofort von aufgerufen werden) Sie, aber später durch die Funktion, die Sie aufrufen).
Die Tatsache, dass das zugrunde liegende System ereignisgesteuert ist, ist orthogonal zur Verwendung von verzögerten Rückrufen. Sie können sich eine (sehr langsame) Version von node.js vorstellen, die einen Thread für jede Operation gestartet und dann Ihren angegebenen Rückruf aufgerufen hat, als der Thread seine Arbeit beendet hat, ohne Ereignisse zu verwenden. Das ist natürlich ein schreckliches Modell, aber es zeigt meinen Standpunkt :-)
quelle
Die Funktionsweise eines verzögerten Rückrufs ist jedes Mal, wenn Sie einen Rückruf hinzufügen, dieser Rückruf an ein Array weitergeleitet. Wenn dann die Methode
.resolve()
oder.resolveWith()
für das zurückgestellte Objekt aufgerufen wird, ist alles.done()
Rückrufe im Array in der angegebenen Reihenfolge ausgeführt.Nun können wir uns ansehen, was ein verzögertes Objekt ist. Nehmen Sie den folgenden Ausschnitt als Beispiel.
Was wir jetzt haben, ist ein zurückgestelltes Objekt und das Versprechungsobjekt des zurückgestellten Objekts. Das latente Objekt hat die gleichen Methoden wie das Versprechen Objekt, aber das Versprechen Objekt nur die Methoden hat
.done()
,.fail()
und.always()
die verwendet werden , Rückrufe für die jeweiligen auf das latente Objekt hinzuzufügenevent
. Das zurückgestellte Objekt hat jedoch vor allem.resolve()
und vor allem mehrere andere Methoden.reject()
. Wenn diese Methoden für das zurückgestellte Objekt aufgerufen werden, werden alle Rückrufe aufgerufen..resolve()
löst die.done()
und.always()
Rückrufe aus, während die.reject()
Methode die.fail()
und.always()
Rückrufe aufruft .Im Allgemeinen wird das zurückgestellte Objekt in einem privaten Bereich ausgeblendet, und das Versprechungsobjekt wird von der Funktion zurückgegeben, damit Rückrufe darauf platziert werden können. Das verzögerte Objekt wird später aufgelöst, z. B. nach Abschluss einer Ajax-Anforderung oder nach dem Laden eines Bildes, nach einem setTimeout usw. Es ist auch wichtig zu wissen, dass ein verzögertes Objekt nur einmal aufgelöst werden kann. Wenn es bereits gelöst ist, werden seine Rückrufe sofort aufgerufen.
Hier ist ein weiteres Beispiel, das ich benutze:
Weitere Informationen zur
$.Deferred()
Methode und zu zurückgestellten Objekten von jQuery finden Sie unter http://api.jquery.com/category/deferred-object/.quelle
Ich bin mir nicht sicher, aber ich glaube, ein verzögerter Rückruf bezieht sich auf einen asynchronen Rückruf.
Die beste Erklärung fand ich unter http://www.nodebeginner.org
In diesem Beispiel ist wahrscheinlichExpensiveFunction eine nicht blockierende (oder asynchrone) Funktion. Dies bedeutet, dass es nicht sofort ausgeführt wird, sondern in einer sogenannten Ereignisschleife abgelegt wird. Der Thread node.js setzt die Ausführung fort, entscheidet sich jedoch zu einem bestimmten Zeitpunkt dafür, etwas aus der Ereignisschleife auszuführen. Wenn die Ausführung von "probablyExpensiveFunction" abgeschlossen ist, wird sie aufgerufen. Wenn die Ausführung von "probablyExpensiveFunction" abgeschlossen ist, wird der als Parameter übergebene (zurückgestellte) Rückruf aufgerufen.
Als Beispiel für die wahrscheinlich teure Funktion können Sie fs.readFile nehmen
quelle
.resolve()
oder.reject()
auf dem ursprünglichen zurückgestellten Objekt aufrufen , wird die Liste der Rückrufe aufgerufen.JavaScript ist Single-Threaded, so dass Sie nicht in Threads denken können, um dies zu verstehen. Hier ein Beispiel für reguläre und asynchrone Rückrufe mit jQuery:
quelle
Mit verzögerten Rückrufen (auch Promices genannt ) können Sie sequenziellen asynchronen Code schreiben, ohne Schmerzen und Rückruf-Spaghetti:
'when' lässt Sie warten, bis Funktionen parallel zurückkehren, und
then
kann nacheinander verkettet werden.Eine Anmerkung: jQuery verzögert ! = Promices / A , ihre Syntax ist etwas anders.
Es gibt gute Artikel zum Thema: einen im IEBlog und einen in einem zufälligen Blog , ein Buch und eine beliebte Stackoverflow-Frage
quelle