Also habe ich ein Problem mit JavaScript Promises. Ich verwende native Implementierung, um Abhängigkeiten zu reduzieren.Wie man promise.all auf verschachtelte provect.all warten?
Ein illustratives Beispiel für das, was ich brauche.
Ich muss Listen von Büchern, Buchautoren und Käufe abrufen. Ich brauche auch ein Autorenprofil für jeden der Autoren. Nachdem ich all das bekommen habe, muss ich eine nette Sammlung von Autoren mit ihren Büchern und der Einkaufsliste für jedes der Bücher erstellen.
Listen und Profile sind separate API JSON-Aufrufe. Die einzige Abhängigkeit besteht darin, dass ich eine Liste von Autoren benötige, um Autorenprofile zu erhalten.
Ich habe das mit Promises gelöst. Ich verwende Promise.all, um 3 API JSON-Anfragen für Autoren, Bücher und Käufe zu erhalten. Ich benutze noch eine weitere Promise.all, um alle Profile für jeden der Autoren zu bekommen, die ich bekomme (ich durchlaufe die Liste, mappe URLs für jedes Profil und sende einen Stapel von Anfragen parallel).
Ich führe den Profilantrag Batch sobald ich die Liste der Autoren bekomme, also im "Then" -Handler der Autorenliste zu versprechen.
Nun das Problem:
Um sicher zu sein, dass alle Versprechungen, 3-Listen und alle Profile werden vor meiner Montage der Bibliothek Satzes erfolgen, müsste ich ein Profil Charge von Anfragen senden wenn ich mit allen Listen fertig bin, im ersten Promise.all Then-Handler.
Aber: Bücher Bücher ein Käufe nehmen viel mehr Zeit als die Liste der Autoren und ich möchte nicht auf alle von denen zu senden eine Charge von Profilanforderungen warten, also sende ich es im Then - Handler der Autor-Liste Versprechen, damit diese beginnen, sobald ich die Informationen habe.
Ein verschachteltes Promise.all zählt jedoch nicht zu seinem übergeordneten Promise.all Then-Handler, also da meine FinalFunction im Then des Top-Level-Promise.all ist, kann es (und manchmal auch) vor dem Nested feuern Promise.all hat alle Autorenprofile abgerufen.
Ich muss in der Lage sein, alle Promise-Anfragen so schnell wie möglich zu starten, aber nur der Stapel der Autor-Anfragen hängt davon ab, dass ein Versprechen abgeschlossen ist, also muss ich darauf warten. Alle anderen sollten unabhängig voneinander starten.
Pseudo-Code
Promise.all(
requestBooks().then(){},
requestAuthors().then(){
GenerateArrayOfAuthorUris();
// now send a promisifyed batch of per-author requests
Promise.all(
[array of author uris to run requests for]
)
.then(){
// If I run this here, I may not have upper-level requests done
runCalculationsPerAuthorForAllAuthorsBooksPurchasesReceived();
}
},
requestPurchases().then(){},
)
.then(){
// this will fire when 3 top requests are done, but won't wait for
// the nested Promise.all with per-author requests
runCalculationsPerAuthorForAllAuthorsBooksPurchasesReceived();
}
Wenn ich es auf diese Weise zu tun, ich bin durch das Warten auf Anfragen kostbare Zeit verschwenden muss ich Anfragen pro-Autor nicht warten nur auf Start:
Promise.all(
requestBooks().then(){},
requestAuthors().then(){
GenerateArrayOfAuthorUris();
},
requestPurchases().then(){},
)
.then(){
// now send a promisifyed batch of per-author requests
Promise.all(
[array of author uris to run requests for]
)
.then(){
// If I run this here, I may not have upper-level requests done
runCalculationsPerAuthorForAllAuthorsBooksPurchasesReceived();
}
}
Hoffentlich klärt dies, was ich brauche.
Vielen Dank.
Dies ist der Code Beispiel: https://jsbin.com/qizohasofa/edit?js,console
Das ist eine Menge Text und ich habe es (noch) nicht gelesen, aber aus dem Titel klingt es so, als ob du 'Return yourPromiseVar' irgendwo oder so ähnlich vermisst. Können Sie bitte mit Ihrem Code Geige erstellen (ersetzen Sie diese Anfragen mit einigen Timeouts)? – llamerr
Es gibt jetzt eine aktualisierte Version. – Anthony
Klingt so, als hätten Sie vergessen, ein Array-Literal um die "Promise.all" -Parameter zu erstellen, und vergessen, 'Versprechungen 'von' Then'-Callbacks zu wiederholen, die asynchrone Dinge tun. Es würde helfen, statt Pseudo-Code tatsächlich zu zeigen. – Bergi