Warten Sie, bis alle ES6 promises komplett, sogar abgelehnt verspricht
Sagen wir, ich habe eine Reihe von Versprechungen, die Netzwerk-Anforderungen, von denen man scheitern wird:
//http://does-not-exist will throw a TypeError
var arr = [ fetch('index.html'), fetch('http://does-not-exist') ]
Promise.all(arr)
.then(res => console.log('success', res))
.catch(err => console.log('error', err)) //This is executed
Sagen wir, ich will warten, bis alle diese fertig sind, unabhängig davon, ob man versagt hat. Möglicherweise gibt es ein Netzwerk-Fehler nach einer Ressource, ich kann auch ohne Leben, aber wenn ich kann, ich will, bevor ich gehen. Ich möchte zur Verarbeitung von Netzwerk-Ausfälle anmutig.
Seit Verspricht.all
nicht verlassen, keinen Raum für das, was ist die empfohlene Muster für den Umgang mit diesem, ohne Verwendung eines verspricht Bibliothek?
Was muss zurückgegeben werden in dem resultierenden array für zusagen, die abgelehnt?
ES6 verspricht Unterstützung keine solche Methode (und die sind momentan scheinbar langsamer als Bluebird). Hinzu kommt, dass nicht alle Browser oder Suchmaschine unterstützt Sie nur noch. Ich würde stark empfehlen die Verwendung von Bluebird, die mit
Ich denke, Sie bringen die Grund Versprechen.alle haben nicht dieses Verhalten, das ich denke, dass macht Sinn. Dies ist nicht wie es funktioniert, aber eine alternative Sichtweise wäre zu sagen, Versprechen.alle sollen den Wiedereinstieg ein besonderes Versprechen, die nie versagt-und Sie würden die Fehler, die geworfen wurde, als argument repräsentiert die gescheiterten Versprechen.
Zu erweitern, ich würde gerne eine version von Versprechen.alle, die verrechnet wird, wenn eine oder mehr behoben, lehnt aber wenn alle fehlgeschlagen.
Hmm, ich denke nicht so.
ES6 verspricht Unterstützung keine solche Methode (und die sind momentan scheinbar langsamer als Bluebird). Hinzu kommt, dass nicht alle Browser oder Suchmaschine unterstützt Sie nur noch. Ich würde stark empfehlen die Verwendung von Bluebird, die mit
allSettled
erfüllt Ihre benötigen, ohne dass Sie Rollen Sie Ihre eigenen.Ich denke, Sie bringen die Grund Versprechen.alle haben nicht dieses Verhalten, das ich denke, dass macht Sinn. Dies ist nicht wie es funktioniert, aber eine alternative Sichtweise wäre zu sagen, Versprechen.alle sollen den Wiedereinstieg ein besonderes Versprechen, die nie versagt-und Sie würden die Fehler, die geworfen wurde, als argument repräsentiert die gescheiterten Versprechen.
Zu erweitern, ich würde gerne eine version von Versprechen.alle, die verrechnet wird, wenn eine oder mehr behoben, lehnt aber wenn alle fehlgeschlagen.
Hmm, ich denke nicht so.
Promise.all
ablehnen werden, sobald one Verheißung lehnt, so dass Ihre vorgeschlagene idiom nicht garantieren, dass alle Verheißungen erfüllt sind.InformationsquelleAutor Nathan Hagen | 2015-07-15
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sicher, Sie brauchen nur ein
reflect
:Oder mit ES5:
Oder in deinem Beispiel:
Einfachere syntax? Ich verstehe nicht, was du meinst.
es ermöglicht Ihnen, herauszufinden, was abgelehnt und was erfüllt und Extrakte, die das problem auf eine wiederverwendbare Betreiber.
In Antwort auf meine eigene Frage, die ich erstellt haben, den folgenden npm-Paket: github.com/Bucabug/promise-reflect npmjs.com/package/promise-reflect
Ich lief in dieses Problem vor einer Weile, und ich habe dieses npm-Paket für ihn: npmjs.com/package/promise-all-soft-fail
InformationsquelleAutor Benjamin Gruenbaum
Benjamins Antwort bietet eine große Abstraktion für die Lösung dieses Problems, aber ich hatte gehofft, für eine weniger abstrahierte Lösung. Der explizite Weg, um dieses Problem zu beheben ist, rufen Sie einfach
.catch
auf der internen verspricht, und wieder den Fehler, von Ihren Rückruf.Einnahme dieses einen Schritt weiter, könnten Sie schreiben eine generische catch-handler, der wie folgt aussieht:
dann können Sie
Das problem mit diesem ist, dass die Gefangenen-Werte wird eine andere Schnittstelle als die nicht-gefangen-Werte, so reinigen Sie diesen, bis Sie vielleicht so etwas machen:
So, jetzt können Sie dies tun:
Dann TROCKEN zu halten, bekommen Sie auf Benjamins Antwort:
wo es jetzt aussieht wie
Die Vorteile des zweiten Ansatzes liegen in seiner abstrahierten und TROCKEN. Der Nachteil ist, Sie haben mehr code, und Sie haben sich daran zu erinnern zu reflektieren, die alle Ihre Versprechungen zu machen, die Dinge konsistent.
Ich würde charakterisieren meine Lösung als explizite und KÜSSEN, aber in der Tat weniger robust. Nicht in der Schnittstelle garantieren, dass Sie genau wissen, ob die Versprechen, erfolgreich oder fehlgeschlagen.
Zum Beispiel könnten Sie haben:
Diese nicht verfangen
a.catch
, soGibt es keine Möglichkeit zu sagen, was man war tödlich und das war nicht war. Wenn das wichtig ist, dann sind Sie gehen zu wollen, um die Durchsetzung und die Schnittstelle, die verfolgt, ob es erfolgreich war oder nicht (was
reflect
tut).Wenn Sie nur wollen, um Fehler zu behandeln anmutig, dann können Sie so behandeln Sie Fehlermeldungen wie " undefined Werte:
In meinem Fall, brauche ich nicht zu wissen, die Fehler oder wie man es fehlgeschlagen ist-ich habe nur Sorge, ob ich das Wert ist oder nicht. Ich lasse die Funktion generiert das Versprechen sorgen um die Protokollierung der jeweiligen Fehler.
So, der rest der Anwendung können Sie ignorieren die Fehler, wenn es will, und behandeln es als einen undefinierten Wert, wenn es will.
Möchte ich mein high-level-Funktionen fehlschlagen, sicher und sich keine sorgen über die details, warum der Abhängigkeiten ist fehlgeschlagen, und ich habe auch lieber KÜSSEN, um zu TROCKNEN, wenn ich nach stellen, die Kompromiss-das ist letztlich der Grund, warum ich entschieden nicht zu verwenden
reflect
.Promise
s. Während Ihrreflect
verbessert die Wiederverwendung von code, er legt auch eine andere Ebene der Abstraktion. Seit Nathans Antwort bisher erhalten nur einen Bruchteil der upvotes im Vergleich zu dir, ich Frage mich, ob dies ein Indiz für ein Problem mit seiner Lösung, die ich noch nicht erkannt, noch nicht.diese Lösung ist konzeptionell weniger den Klang, da es behandelt Fehler Werten und nicht zu trennen-Fehler von nicht-Fehler. Zum Beispiel, wenn man von den Versprechen löst berechtigterweise auf einen Wert, der geworfen werden kann (was durchaus möglich ist), diese bricht ganz schlecht.
So zum Beispiel
new Promise((res, rej) => res(new Error('Legitimate error'))
wäre nicht unterscheidbar vonnew Promise(((res, rej) => rej(new Error('Illegitimate error'))
? Oder weiter, Sie wäre nicht in der Lage zu filtern, die durchx.status
? Ich werde diesen Punkt meiner Antwort, damit der Unterschied klarerDer Grund, warum das eine schlechte Idee ist, weil es Bindungen, die Versprechen, die Umsetzung auf einen bestimmten Anwendungsfall, immer nur in einer bestimmten
Promise.all()
Variante, es wird dann ebenfalls Pflicht, die Versprechen der Verbraucher, zu wissen, dass ein bestimmtes Versprechen nicht ablehnen, sondern schlucken es Fehler. In der Tat diereflect()
Methode gemacht werden konnten, weniger 'Abstrakt' und mehr explizit durch AufrufPromiseEvery(promises).then(...)
.Die Komplexität der Antwort oben im Vergleich zu Benjamins sollte sagen viel über diese Lösung.InformationsquelleAutor Nathan Hagen
Ich wirklich wie Benjamins Antwort, und wie er dreht sich im Grunde alle Versprechen in die immer-auflösen-aber-manchmal-mit-Fehler-wie-ein-Ergebnis lieben. 🙂
Hier ist mein Versuch, auf Ihre Anfrage nur, wenn Sie waren auf der Suche nach alternativen. Diese Methode, einfach behandelt, Fehler als gültige Ergebnisse, und ist codiert, ähnlich zu
Promise.all
ansonsten:settle
. Wir haben das auch in bluebird, ich mag reflektieren besser, aber dies ist eine praktikable Lösung für, wenn du diese für ein array.OK, abrechnen wird ein besserer name in der Tat. 🙂
Das sieht viel wie das explizite Versprechen, Bau-antipattern. Es sollte angemerkt werden, dass man niemals schreiben sollte, eine solche Funktion selbst, sondern verwenden Sie die eine, die Ihre Bibliothek versorgt (OK, native ES6 ist ein bisschen dürftig).
Könnten Sie bitte die Verwendung der
Promise
Konstruktor richtig (und zu vermeiden, dassvar resolve
Dingens)?Bergi, fühlen Sie sich frei, zu ändern, die Antwort jedoch, die Sie für notwendig erachten.
InformationsquelleAutor Kuba Wyrostek
Den
Promise.all
schlucken alle abgelehnt Versprechen und zu speichern, die Fehlermeldung in eine variable, so wird es wiederkommen, wenn all die Versprechungen aufgelöst haben. Dann können Sie erneut auslösen, den Fehler aus, oder tun, was auch immer. Auf diese Weise, ich denke, Sie würde bekommen, die letzten Ablehnung statt der ersten.err.push(error)
, so dass alle Fehler könnte sprudelte.InformationsquelleAutor martin770
Ich hatte das gleiche problem und habe es gelöst in der folgenden Weise:
In diesem Fall
Promise.all
warten darauf, dass jede Verheißung wird kommen, inresolved
oderrejected
Zustand.Und mit dieser Lösung sind wir "stoppen
catch
Ausführung" in einer nicht blockierenden Weise. In der Tat, wir sind nicht zu stoppen, nichts, wir einfach wieder zurückPromise
in einem pending-Zustand gibt eine anderePromise
wenn es behoben ist, nach dem timeout.Promise.all
. Ich bin auf der Suche nach einem Weg zu hören, wenn alle zusagen wurden aufgerufen, aber nicht auf Sie selbst. Danke.die Methode
all()
tut, es wartet auf die Erfüllung aller Verheißungen oder Ablehnung zumindest eines davon.das ist wahr, aber es muss nicht nur warten, es tatsächlich aufruft/startet/startet den Prozess. Wenn Sie wollte, um Feuer auf die Verheißungen, woanders wäre das nicht möglich, becase
.all
feuert alles.hoffe, dies wird sich ändern Sie Ihre Meinung jsfiddle.net/d1z1vey5
Ich stehe korrigiert. Bis jetzt dachte ich, Verspricht nur dann, wenn jemand ruft Sie (ein.k.ein
then
oder eine.all
anrufen), aber Sie laufen, wenn Sie erstellt.InformationsquelleAutor user1016265
Diese sollte im Einklang mit wie F es tut:
InformationsquelleAutor mpen
Es ist ein Vorschlag für eine Funktion, die dies nativ, in vanilla Javascript:
Promise.allSettled
. Es ist derzeit auf Stufe 3, und wird sehr wahrscheinlich zu machen, in der offiziellen Spezifikation. Es ist sehr ähnlich zu derreflect
Funktion in diese andere Antwort. Hier ist ein Beispiel, von dem Vorschlag-Seite. Vor, Sie hätte zu tun:Mit
Promise.allSettled
stattdessen die oben genannten entspricht:Sobald dieser wird Teil der Spezifikation und Browser implementieren, werden Sie in der Lage, es auf modernen Browsern ohne Bibliotheken.
InformationsquelleAutor CertainPerformance
Hier mein custom
settledPromiseAll()
Im Vergleich zu
Promise.all
Wenn alle zusagen sind behoben, es führt genau so, wie der standard.
Wenn man mehr verspricht, werden abgelehnt, es gibt die erste abgelehnt, viel die gleiche wie die standard, aber anders als er wartet, bis alle Versprechungen zu beheben/ablehnen.
Für die mutigen könnten wir ändern
Promise.all()
:VORSICHTIG. In der Regel können wir nie ändern, built-ins, da es brechen könnte andere, nicht Verwandte JS-Bibliotheken oder die Auseinandersetzung mit zukünftigen Veränderungen zu JS-standards.
Meine
settledPromiseall
ist rückwärts kompatibel mitPromise.all
und erweitert seine Funktionalität.Menschen, die Entwicklung von standards-warum nicht diese auf ein neues Versprechen-standard?
InformationsquelleAutor Edward
Ich denke, das folgende bietet einen etwas anderen Ansatz... vergleichen
fn_fast_fail()
mitfn_slow_fail()
... obwohl letzteres nicht scheitern... Sie können überprüfen, ob eine oder beidea
undb
ist eine Instanz vonError
undthrow
dassError
wenn Sie möchten, es zu erreichencatch
block (z.B.if (b instanceof Error) { throw b; }
) . Finden Sie die jsfiddle.InformationsquelleAutor drmrbrewer
Ich tun würde:
InformationsquelleAutor FRocha
Habe ich mit folgenden codes seit ES5.
Die Nutzung der Signatur ist nur, wie
Promise.all
. Der wesentliche Unterschied ist, dassPromise.wait
warten für alle verspricht, beenden Ihre Arbeitsplätze.InformationsquelleAutor user2273990
Ich weiß, dass diese Frage hat viele Antworten, und ich bin sicher, muss (wenn nicht alle) sind richtig.
Allerdings war es sehr schwer für mich zu verstehen, die Logik - /Fluss dieser Antworten.
Also habe ich mir die Original-Implementierung auf
Promise.all()
, und ich versuchte, Sie zu imitieren, dass Logik - mit Ausnahme der nicht zu stoppen die Ausführung, wenn ein Versprechen gescheitert.Erklärung:
- Schleife über die Eingabe
promisesList
und führen Sie die einzelnen Versprechen.- Egal, ob das Versprechen gelöst oder abgelehnt: speichern Sie das Versprechen, das Ergebnis in eine
result
array nach derindex
. Speichern Sie auch die resolve/ablehnen-status (isSuccess
).- Wenn alle Versprechen abgeschlossen, kehren Sie ein Versprechen mit dem Ergebnis aller anderen.
Beispiel verwenden:
Promise.all
selbst, es gibt zu viele Dinge, die schief gehen wird. Ihre version nicht, um leere Eingaben für Beispiel.InformationsquelleAutor Gil Epshtain
Ich weiß nicht, welche Versprechen, die Bibliothek, die Sie verwenden, aber die meisten haben so etwas wie allSettled.
Edit: Ok, da wollen Sie einfach ES6 ohne externe Bibliotheken, es gibt keine solche Methode.
In anderen Worten: Sie müssen die Schleife über Ihrem Versprechen manuell und lösen eine neue kombiniert Versprechen, sobald alle zusagen erfüllt sind.
InformationsquelleAutor Sebastian S