2016-07-12 22 views
0

Nehmen wir an, ich habe eine bedingte Anweisung, nach der ein Versprechen erstellt wird. Ich möchte eine gemeinsame .catch() Funktion erstellen, die jedes Mal aufgerufen wird, wenn eine meiner Versprechen fehlschlägt. Wenn ich jedoch später Fanganweisungen anhefte - sie werden anders behandelt, warum?Warum `.catch()` fängt nichts ein und wird mehrfach ausgeführt?

var p1; 
var condition = true; 

if (condition) { 
    p1 = new Promise(function(resolve, reject) { 
    setTimeout(function() { reject('BREXIT!'); }, 1000); 
    }); 
} else { 
    p1 = new Promise(function(resolve, reject) { 
    setTimeout(function() { resolve('REMAIN!'); }, 1000); 
    }); 
} 

p1.catch(function(e) { console.error("1 I CATCH", e); }); 
p1.catch(function(e) { console.error("2 I CATCH", e); }); 
p1.then(function(e) { console.log("ALL DONE"); }); 

// Actual output: 
// 
// 1 I CATCH BREXIT! 
// 2 I CATCH BREXIT! 
// Uncaught (in promise) BREXIT! 
// 
//============================== 
// Expected output: 
// 
// 1 I CATCH BREXIT! 
// ALL DONE 

Sie können hier mit diesem Code spielen: http://jsbin.com/lopuyid/edit?js,console

Ich verstehe, dass ich, indem die ganze Versprechen Schöpfung separate Funktion kann dieses Problem lösen, und alles verketten. Meine Frage ist, warum .catch() Aussagen nicht wirklich fangen und statt einer ausgeführt werden? Verkettet nicht Dinge A.f1().f2() das gleiche wie A.f1(); A.f2() tun?

aktualisieren

Wenn jemand auf dieser Seite durch Web-Suche kommen, lesen Sie die große Links unter diesem Beitrag. Um das Problem schnell zu beheben, ohne zu viel Code zu ändern, sollten Sie die gleichen Versprechen nach jedem Fang aktualisieren und dann:

p1 = p1.catch(function(e) { console.error("1 I CATCH", e); }); 
p1 = p1.catch(function(e) { console.error("2 I CATCH", e); }); 
p1 = p1.then(function(e) { console.log("ALL DONE"); }); 
+3

Sie registrieren mehrere Handler mit demselben Versprechen. Wenn dieses Versprechen abgelehnt wird, werden alle '.catch()' Handler auf dem gleichen Versprechen aufgerufen, und keiner der auflösenden Handler wird für dieses Versprechen aufgerufen. Sie sind wie Event-Handler. Alle Ereignishandler mit demselben Versprechen werden aufgerufen. Das eine beeinflusst das andere nicht. Das ist verzweigend. Wonach du fragst, ist Verkettung. Versuchen Sie 'p.catch(). Catch()'. Das ist Verkettung und wird anders funktionieren. Der erste '.catch()' - Handler wirkt sich auf die zweite Kette aus. – jfriend00

+1

* "Verkettet die Dinge nicht A.f1(). F2() genauso wie A.f1(); A.f2()?" *. - Nein, ist es nicht. Bei der Verkettung gibt f1() ein ganz neues Versprechen mit dem zusätzlichen Verhalten (catch) zurück, das f2() beeinflusst. – noppa

+1

Siehe [Verkettung vs. Verzweigung] (http://stackoverflow.com/questions/32216619/is-there-a-difference-breath-then-then-vs-promise-then-promise-then/32216660#32216660) und [Stacks vs. Chaining] (http://stackoverflow.com/questions/29853578/understanding-javascript-promises-stacks-and-chaining/29854205#29854205). Das 'p.then (...); p.then (...) 'ist völlig anders als' p.then (...). dann (...) '. – jfriend00

Antwort

0

aus dem Code, was Sie erwarten, wenn reject zum ersten Mal auftritt, 1 I CATCH BREXIT! sollte ausdenken. Wenn es zum zweiten Mal auftritt, sollte 2 I CATCH BREXIT! auftauchen. Aber so funktioniert Javascript nicht. Es ist ereignisbasiert und Sie können mehrere Aktionen für ein Ereignis registrieren.

Also im Grunde, indem Sie:

p1.catch(function(e) { console.error("1 I CATCH", e); }); 
p1.catch(function(e) { console.error("2 I CATCH", e); }); 

Sie 2 unabhängige Ereignisse registrieren, die auf reject ausgelöst werden.