Ich beginne mit E6 Versprechen. Ich mag sie sehr, aber es gibt ein entscheidendes Konzept zur Fehlerbehandlung, das ich nicht verstehe und das ich gerne etwas genauer erklären würde.ES6 Versprechen Fehler sprudeln nicht wie erwartet
Lassen Sie uns die folgende einfache Funktion übernehmen, die ein Versprechen zurückgibt:
function promiseString(str, timeout, doResolve) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (doResolve) {
resolve(str);
} else {
reject(new Error("Rejecting " + str));
}
}, timeout);
});
}
Es ist ziemlich einfach ist, gibt nur ein Versprechen für die Zeichenfolge, die an sie übergeben wurde, und die Ursachen, die gelöst oder abgelehnt versprechen werden (basierend auf dem dritten Argument) in "Timeout" Millisekunden.
Ich kann dies vollständig verbrauchen wie erwartet wie folgt:
promiseString("One", 100, true)
.then((str) => { console.log("First then is " + str); return promiseString(str + " two", 100, true); })
.then((str) => { console.log("Second then is " + str); return promiseString(str + " three", 100, true); })
.then((str) => console.log(str))
.catch((err) => console.error(err));
Wenn auf von „true“ auf „false“ in einem der Anrufe in dieser Kette das dritte Argument ändern, wird mein Fehler gefangen wie erwartet und sende an console.error().
Doch jetzt stellen Sie sich die folgenden (ähnlich albern) Funktion für ein vielversprechendes Objekt konstruieren:
function DoublePromiser(str1, str2, doResolve) {
this.promise = new Promise((resolve, reject) => {
promiseString(str1, 100, doResolve)
.then((s1) => promiseString(s1 + str2, 100, doResolve))
.then((s2) => resolve(s2));
});
}
jetzt Stellen Sie sich vor, dass ich diesen Code verbrauchen wie folgt, mit allem, was zu lösen und nichts Ablehnung (doResolve wird auf true):
var dp = new DoublePromiser("Big", "Promise", true);
dp.promise
.then((s) => console.log("DoublePromise: " + s))
.catch((err)=>console.log("I did catch: ", err.message));
Wie zu erwarten, sehe ich folgend in der Konsole:
DoublePromise: BigPromise
aber jetzt habe ich den verzehrenden Code ändern, das Setzen von doResolve auf „false“ (was bewirkt, dass mein Versprechen Routine ablehnen):
var dp = new DoublePromiser("Big", "Promise", false);
dp.promise
.then((s) => console.log("DoublePromise: " + s))
.catch((err)=>console.log("I did catch: ", err.message));
Wegen meines Verständnisses davon, wie Fehler sollten „sprudeln“, ich würde erwarten, Die Konsole loggt sich wie folgt ein:
I did catch: Rejecting Big
Aber das tut es nicht. Stattdessen zeigt die Konsole eine nicht erfasste Fehler:
Uncaught (in promise) Error: Rejecting Big
ich nur bekommen, was ich erwarten (und Lust), wenn ich einen Haken an dem Ende der Kette in der DoublePromiser hinzuzufügen, wie folgt aus:
function DoublePromiser(str1, str2, doResolve) {
this.promise = new Promise((resolve, reject) => {
promiseString(str1, 100, doResolve)
.then((s1) => promiseString(s1 + str2, 100, doResolve))
.then((s2) => resolve(s2))
.catch((err) => reject(err)); // ADDING THIS TO MAKE IT WORK
});
}
Jetzt bekomme ich was ich erwarte, der Fehler ist nicht aufgefallen. Aber das scheint der ganzen Idee zu widersprechen, dass Fehler auftauchen, und es scheint seltsam, einen Fehler zu finden, nur um den gleichen Fehler zurückzuweisen.
Fehle ich eine Möglichkeit, dies einfach zur Arbeit zu bringen?
Fehle ich ein grundlegendes Konzept?
Diese 100% theoretischen Fragen mit erfundenem Code, die kein wirkliches Problem darstellen, funktionieren beim Stack-Overflow nur schlecht. – jfriend00
Auch Sie verwenden die Verheißung Konstruktor Anti-Muster: https://github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns – jfriend00
@estus - Ich habe ihren Titel bearbeitet. – jfriend00