Sequentielle Funktionsaufrufe in javascript
Möchte ich Eine Funktion die Ausführung beendet und nur nach, dass die Funktion B start-ausführen. Wenn ich rufen Sie die Funktion A und Funktion B, es scheint, beide gleichzeitig ausgeführt werden. Und nach der Funktion B beendet ist, möchte ich nennen, eine Dritte Funktion update_dropdown().
Mein code sieht wie folgt aus:
function A {
for (var i = 0; i < 5; i++) {
var promise = $.get(url+i);
$.when(promise).then(function () {
$.post(url);
});
}
}
function B {
var x = $.get(url);
var promise = $.post(url+x);
$.when(promise0).then(function () {
update_dropdown();
});
}
Bitte können Sie mir sagen, wie ich diese 3 Funktionsaufrufe passieren hintereinander.
- Nicht ganz sicher, was Ihr Ziel ist, können Sie erklären, ein wenig mehr?
- Vorausgesetzt: 1. Sie rufen Eine Funktion, möchten Sie warten, für die $.Holen Sie abgeschlossen ist, dann den Sie anrufen möchten, Funktion B, und schließlich, wenn B abgeschlossen ist, die Sie anrufen möchten update_dropdown()?
- Wenn Sie möchten, eine genaue Antwort, Sie haben wirklich zu wissen, was Sie wollen, dass die aufrufsequenz zu werden. Dein code macht nicht eine ganze Menge Sinn (und es ist pseudo-code), so dass es nicht ganz klar, welche Reihenfolge Sie tatsächlich wollen, dass die Dinge geschehen. Zum Beispiel, in
A()
, wollen Sie fünf$.get()
Operationen parallel und dann, wenn Sie alle komplett, ein$.post()
Betrieb? InB()
, tun Sie wirklich wollen, zu tun, ein$.get()
und dann ohne zu warten, für nichts, tun ein$.post()
? - Ja @Pepto Ihre Annahme richtig ist, "Sie rufen Eine Funktion, möchten Sie warten, für die $.Holen Sie abgeschlossen ist, dann den Sie anrufen möchten, Funktion B, und schließlich, wenn B abgeschlossen ist, die Sie anrufen möchten update_dropdown()"
- In der Funktion-Ein, ich will 5 sequentielle get&post-Anfragen. Zunächst erhalten Sie dann post. Dies muss geschehen, 5x. Dann die Funktion-B, ausführen muss. In B gibt es einen einzigen $bekommen, von denen ich einige Wert, und dann nach diesem Wert. (sorry, dieser Teil ist nicht in meinem code verursacht einige Verwirrung gibt.) Dann rufen Sie die Funktion update_dropdown().
- Tun die ersten 5 Anfragen bekommen, die dann posten, müssen serialisiert werden (2. legen Sie wartet für den 1. abgeschlossen ist)? Oder kann Sie laufen alle auf einmal und nur warten, bis alle von Ihnen getan werden, bevor Sie fortfahren?
- Und die
url
im pseudo-code ... vermutlich ist es unterschiedlich? Ich sehe keinen Grund für den Aufruf der gleichen Ressource, die viele Male in dieser Weise. - ja die url ist unterschiedlich.
- 1(get,post),2(get,post),3(get,post),4(get,post),5(get,post).
- OK, damit ist die option 1 in meiner Antwort, wenn Sie wollen, dass Sie alle serialisiert. Es wäre schneller, führen Sie von Anfang bis Ende, wenn Sie laufen konnte jedes paar parallel, aber wenn #2-pair muss die Ergebnisse von #1 paar oder muss der server bereits verarbeitet #1 paar, dann würde es sequenziell sein.
Du musst angemeldet sein, um einen Kommentar abzugeben.
OK, es ist immer ein wenig klarer, was Sie eigentlich wollen (basierend auf Ihren letzten Kommentare zu Anschrift, Klärung von Fragen) aber es gibt noch mindestens zwei Optionen offen.
Für eine operation wie diese, werden Sie wahrscheinlich wollen, um die Vorteile einer Reihe von Versprechen features:
.then()
handler und der master-Versprechen löst sich nur, wenn alle angekettet verspricht aufgelöst haben (so eine Art built-in$.when()
die zimmerreserviereung, ohne das explizit zu nennen$.when()
).A()
undB()
, dann wird der Anrufer diese Funktionen können Sie überwachen, wenn Sie fertig sind mit dem Versprechen Methoden, die dann können Sie die KetteA().then(B)
um die Sequenz von beiden..then()
- handler-Funktion in der Kette als erstes argument an die.then()
- handler-Funktion, so, wenn Sie die Vorherige Daten für die nächste operation, es ist richtig, es zu verwenden.So, mit all diesen Funktionen, es geht nur noch darum, die richtige Gerüst, um den code zu implementieren, die genaue Sequenzierung, die Sie wollen. Hier sind zwei verschiedene Möglichkeiten:
Option 1: Wenn Sie serialisieren möchten alles in
A()
so, dass alle 10 Anfragen geschehen in serial Mode (next geht man nur, wenn der vor einem fertig ist), dann könnte es so Aussehen:Option 2: Wenn Sie möchten, dass die 5 Paare von Anfragen in
A()
parallel laufen, mit nur den letzten TeilA()
warten, bis die 5 Paare des requests fertig sind, dann könnte es so Aussehen:Diese verwenden das Konzept, dass, wenn Sie zurückkehren, ein Versprechen von einem
.then()
- handler-Funktion, dann wird es eine Kette mehrere asynchrone Operationen zusammen, und die master-Versprechen ist nur gelöst, wenn alle die verkettete Operationen aufgelöst werden. Dies ist sehr mächtig für die Sequenzierung mehrere ajax-Operationen, und Sie können sogar tun Sie es für Operationen in einer Schleife, wie Sie haben.A()
serialisiert werden. Auch, können Sie zeigen Sie uns Ihre tatsächliche code? Wir können nicht wirklich debug pseudo-code. Wenn Anfragen von FunktionA()
undB()
sind immer gemischt, dann ist etwas nicht richtig implementiert, weil weder option 1 oder option 2 wird das tun.unattachSTARs()
sollten am Ende mitreturn $.when.apply($,promises);
, nichtreturn $.when.apply($.promises);
. Beachten Sie das Komma anstelle der Periode.update_AI_starLists()
sollten am Ende mit}).then(update_dropdown));
, nicht}).then(update_dropdown()));
. Sie setzen nicht()
auf eine Funktion, die Sie vorbei sind, als Referenz, damit es aufgerufen werden kann später.Etwas, wie das funktionieren sollte
Beachten Sie die Verwendung von einem array zu halten, die verspricht, dann mit
$.when
mitapply()
Feuer einen Rückruf, wenn alle ajax-Anfragen, die in die Schleife beendet ist.A()
und inB()
als die OP und die fehlenden zwei Operationen.A
die$.when
Aufruf innerhalb der Schleife in der OP-code, der den Aufruf derB
- Funktion für jede Anfrage, bin ich davon ausgegangen, dass war das problem und das der Punkt war, um Sie aus der Schleife. In derB
Funktion fehlt mir ein Aufruf$.get(url)
, ansonsten ist es das gleiche, aber die OP ist Berufung$.get(url)
fünf mal inA
, so dass ich nicht denke, dass es sehr sinnvoll zu nennen, dass die Funktion wieder inB
, und wenn Sie es war, die Verfahren zu warten, bis beide Anrufe zu beenden, wäre das gleiche wie inA
.when()
, aber Sie simulieren$.when(...)
genauer mit$.when.apply($, xhr);
wo Sie gehen$
stattundefined
sothis
eingestellt ist$
.$.when( $.post(url) ).then(update_dropdown);
kann nur sein:$.post(url).then(update_dropdown);
return
aus jeder Funktion, die Art und Weise, werden Sie in der Lage, Haken auf es alle getan, und Sie zusammensetzen.Annahmen Annahmen ...
Lassen Sie uns davon ausgehen, dass :
get
ist die gleiche wie die für die entsprechendepost
Erste, eine utility-Funktion :
dann A und B, die beide rufen das Dienstprogramm :
und schließlich ein Ausdruck, der nennt A und B :
Sollte es einigermaßen einfach zu passen Sie diesen code, wenn die Annahmen 1 und 2 sind falsch.
Wenn Annahme 3 ist falsch, dann wird mehr erfordern umfangreiche änderungen.
A
.Nennen wir unsere Wahl-Funktion in unserer Art und Weise mit Hilfe von jquery Deferred-Objekt.
Es ist sehr einfach, lassen Sie sehen, Sie erfolgreich ausgeführt werden Beispiel:
pipe
ist veraltet, seit Jahren?Javascript ohne zusätzliche Arbeit ist single threaded. das bedeutet, Funktionen können nicht gleichzeitig ausgeführt werden. aber das problem ist, dass die $.get() und $.post () - Aufrufe asynchron sind. das bedeutet, dass Sie immer dann ausgeführt, wenn die angeforderten Daten kommt Ihr Kunde. (first come first serve)
eine Lösung wäre, um auszuführen, Funktion B, nachdem alle Ergebnisse, ob Eine angekommen ist, oder zurück zu halten alle Ergebnisse und behandeln alle Daten auf einmal, dann laufen
update_dropdown()
.