Ich habe Probleme, JavaScript zu verstehen promises
. Ich habe folgenden Code geschrieben:
var p = new Promise(function(resolve,reject){
reject(Error("hello world"));
});
setTimeout(()=>p.catch(e=>console.log(e)),5000);
Ich sehe dies sofort in meiner Chrome-Entwicklerkonsole:
Aber nachdem ich 5 Sekunden gewartet habe, ändert sich die Nachricht automatisch in Schwarz wie in diesem Bild:
Ich habe dieses Verhalten noch nie zwischen meinem JavaScript-Code und einer Entwicklerkonsole gesehen, bei der mein JavaScript-Code "vorhandene Inhalte ändern" kann.
Also habe ich mich entschlossen, resolve
durch Schreiben dieses Codes zu prüfen, ob die gleiche Situation auftritt :
var p = new Promise(function(resolve,reject){
resolve("hello world");
});
setTimeout(()=>p.then(e=>console.log(e)),5000);
In dieser Situation zeigt meine Entwicklerkonsole jedoch erst 5 Sekunden später etwas an, auf das sie dann druckt hello world
.
Warum werden die resolve
und reject
so unterschiedlich behandelt, wenn sie aufgerufen werden?
EXTRA
Ich habe auch diesen Code geschrieben:
var p = new Promise(function(resolve,reject){
reject(Error("hello world"));
});
setTimeout(()=>p.catch(e=>console.log("errors",e)),5000);
setTimeout(()=>p.catch(e=>console.log("errors 2",e)),6000);
setTimeout(()=>p.catch(null),7000);
Dies führt zu mehreren Ausgaben an die Entwicklerkonsole. Roter Fehler zum Zeitpunkt 0, Rot wechselt zum Zeitpunkt 5 Sekunden mit dem Text zu Schwarz errors hello world
, dann eine neue Fehlermeldung zum Zeitpunkt 6 Sekunden errors 2 hello world
, dann eine rote Fehlermeldung zum Zeitpunkt 7 Sekunden. Jetzt bin ich sehr verwirrt darüber, wie oft ein reject
tatsächlich aufgerufen wird ... Ich bin verloren ...
var p = new Promise(function(resolve,reject){ reject(Error("hello world")); });
kann idiomatischer und prägnanter geschrieben werden alsvar p = Promise.reject(Error("hello world"));
:-)Antworten:
Wow, das ist echt cool. Ich hatte noch nie zuvor gesehen, dass die Konsole das tat. (Es hat jedoch andere Formen von dynamischem Verhalten, also ...) Folgendes ist los:
Im ersten Fall wird die Codeausführung von allem außerhalb
setTimeout
des Rückrufcodes abgeschlossen und der Ausführungsstapel wird zurückgegeben, sodass nur " Plattformcode " (wie es die Promises / A + -Spezifikation nennt) ausgeführt wird, im Moment kein Userland-JavaScript-Code. Zu diesem Zeitpunkt wird das Versprechen abgelehnt und nichts hat die Ablehnung behandelt. Es handelt sich also um eine unbehandelte Ablehnung, und devtools meldet sie Ihnen als solche.Dann fünf Sekunden später Ihr Rückruf läuft und fügt eine Ablehnung Handler. Ab diesem Zeitpunkt wird die Ablehnung nicht mehr unbehandelt. Anscheinend arbeiten Chrome / V8 / devtools zusammen, um die unbehandelte Ablehnungswarnung von der Konsole zu entfernen . Stattdessen wird angezeigt, was Sie in Ihrem Ablehnungshandler über ausgeben
console.log
. Wenn Sie den Ablehnungshandler früher anhängen, wird dieser nicht behandelte Ablehnungsfehler nicht angezeigt.Dies geschieht nicht bei der Erfüllung, da die Nichtbehandlung der Erfüllung keine Fehlerbedingung ist. Ablehnung nicht zu behandeln ist.
quelle