Ich versuche zu verstehen, wie man asynchronen Code debuggt, der auf Versprechungen basiert. Mit Versprechen meine ich ECMAScript 6-basierte Versprechen und mit Debuggen meine ich die Verwendung des eingebauten Chrome- oder Firefox-Debuggers.
Ich habe Probleme damit - wenn ein Fehler auftritt, kann ich den Stack-Trace scheinbar nicht abrufen, egal wie ich ihn "ablehne".
Ich habe diese ausprobiert:
console.log(new Error('Error occured'));
throw new Error('Throwing an Error');
return new Error('Error returned by the onRejected function');
reject(new Error('Pass Error to the reject function'));
Aber keiner von diesen gibt den tatsächlichen Fehler im Code oder in der Stapelverfolgung zurück.
Meine Frage ist also: Wie kann man Javascript-Versprechen richtig debuggen?
javascript
promise
es6-promise
YemSalat
quelle
quelle
reject('Error')
Aber können Sie eine jsfiddle posten, damit wir etwas Konkretes haben, mit dem wir arbeiten können?Antworten:
Dies ist ein großartiges Thema, über das man diskutieren kann. Die traurige Nachricht ist, dass dies mit einheimischen Versprechungen ziemlich schwierig ist.
Das Debuggen von rohen ES6-Versprechungen in Chrome ist schrecklich. Dies liegt daran, dass sie Fehler stillschweigend unterdrücken. Wenn Sie einen Fang weglassen, erhalten Sie keinen Hinweis darauf, dass das Versprechen fehlgeschlagen ist.Update: Chrome protokolliert jetzt nicht behandelte Ablehnungen (siehe diesen Link für)Promise.resolve("foo").then(function(){ throw new Error("You will never see this");// silent failure });
In Firefox sind die Dinge etwas besser, da sie eine unbehandelte Ablehnungserkennung durchführen. Es ist jedoch immer noch ein Flakey, und wenn Sie das Versprechen irgendwo vergeben, funktioniert es nicht.
Was kann man also tun?
Bluebird einschließen - es ist eine Obermenge von ES6-Versprechungen und Sie können es direkt austauschen, es hat eine reichhaltigere API, es ist schneller und es hat erstaunliche Stapelspuren . Es wurde mit Blick auf das Debuggen entwickelt und bietet hervorragende Möglichkeiten zur Fehlerbehandlung.
Sobald Sie Bluebird aufgenommen haben, rufen Sie an:
Promise.longStackTraces();
Das wird es etwas verlangsamen (es wird immer noch sehr schnell sein) und Ihnen erstaunliche Fehlermeldungen geben. Zum Beispiel:
Promise.resolve().then(function outer() { return Promise.resolve().then(function inner() { return Promise.resolve().then(function evenMoreInner() { a.b.c.d() }); }); });
Bei nativen Versprechungen - dies ist ein stiller Fehler und sehr schwer zu debuggen - wird bei Bluebird-Versprechungen standardmäßig ein großer roter Fehler in Ihrer Konsole angezeigt, der Folgendes ergibt:
ReferenceError: a is not defined at evenMoreInner (<anonymous>:6:13) From previous event: at inner (<anonymous>:5:24) From previous event: at outer (<anonymous>:4:20) From previous event: at <anonymous>:3:9 at Object.InjectedScript._evaluateOn (<anonymous>:581:39) at Object.InjectedScript._evaluateAndWrap (<anonymous>:540:52) at Object.InjectedScript.evaluate (<anonymous>:459:21)
Sobald Sie mit dem Debuggen fertig sind, können Sie es austauschen und zu den nativen Versprechungen zurückkehren. Persönlich schätze ich es zu wissen, dass ich Fehler in der Produktion habe, deshalb empfehle ich es nicht, aber es ist auf jeden Fall machbar.
quelle
Diese Antwort ist eine Ergänzung zu Benjamin Gruenbaums Antwort: Wenn Sie eine catch-Anweisung in der Versprechenskette verwenden, erhalten Sie die Stapelverfolgung durch error.stack :
Promise.longStackTraces(); function outer() { return Promise.resolve(); } function inner() { return Promise.resolve(); } function evenMoreInner() { a.b.c.d() } Promise.resolve() .then(outer) .then(inner) .then(evenMoreInner()) .catch(function (err) { console.log(err.message); console.log(err.stack); });
Fehlermeldung:
ReferenceError: a is not defined at evenMoreInner (test/test_promise.js:58:17) <<<< HERE's the error! at Context.<anonymous> (test/test_promise.js:64:23)
quelle
stack
Anwesen verpasst und mich gefragt, wohin es gegangen ist, haha!console.log(err)
err.stack nicht enthalten ist. Sie müssenconsole.log(err.stack)
die Details sehen.* Dies beantwortet Ihre Frage nicht direkt, kann aber dennoch hilfreich sein.
Chrome devtools hat kürzlich eine neue Funktion erhalten, die zum Debuggen von asynchronem Code nützlich ist, z. B. Promises.
http://www.html5rocks.com/de/tutorials/developertools/async-call-stack/
Aktivieren Sie grundsätzlich das Kontrollkästchen "asynchron" auf der Registerkarte "Quellen", und Chrome rekonstruiert den Aufrufstapel für Sie so, als wäre es synchroner Code.
quelle
Sie scheinen mit Debug-Tools in Chrome zu arbeiten. Weitere Informationen finden Sie in diesem Thread.
https://code.google.com/p/v8/issues/detail?id=3093
Ich habe nicht überprüft, ob dies bereits in der Entwickler- oder Beta-Version ist, aber ich hoffe, dass es bald sein wird. Es könnte dann im Januar 2015 oder so in der normalen Version enthalten sein (nur eine persönliche Vermutung, absolut kein Versprechen, da ich nicht einmal für Google arbeite).
quelle
Der beste Weg, um versprochene Fehler zu beheben, besteht darin, sich das
unhandledRejection
Ereignis von Ihnen anzuhörenprocess
.Hier erfahren Sie beispielsweise, wie Sie es einrichten und einen Stack-Trace sichern können ...
process.on('unhandledRejection', (reason, p) => { console.log('Unhandled Rejection at: Promise', p, 'reason:', reason); // Stack Trace console.log(reason.stack); });
quelle
Sie können eine console.log () -Anweisung in die .then () -Funktion des Promise-Objekts einfügen: Sie können bei Bedarf auch die .catch () - Anweisung hinzufügen.
genericDbCaller(dbName, collectionName, dbFunctionName, params) { return new Promise((resolve, reject) => { DatabaseContext.instance.getDbConn(dbName) .then((dbConn) => { dbConn.get(collectionName)[dbFunctionName].apply(null, params) .then( (docs) =>{ ----->>> console.log(docs); resolve(docs); }) .catch((e)=>{
quelle