2015-12-11 6 views
6

Prova questo pezzo di codice sulla scheda Console di Chrome o FirefoxCome funziona il "catch" in una catena nativa Promise?

var p = new Promise(function(resolve, reject) { 
    setTimeout(function() { 
     reject(10); 
    }, 1000) 
}) 

p.then(function(res) { console.log(1, 'succ', res) }) 
.catch(function(res) { console.log(1, 'err', res) }) 
.then(function(res) { console.log(2, 'succ', res) }) 
.catch(function(res) { console.log(2, 'err', res) }) 

Il risultato sarà

1 "err" 10 
2 "res" undefined 

che ho provato molti altri esempi, ma sembra che il primo then() restituisce una promessa che risolve sempre e non rifiuta mai. Ho provato questo su Chrome 46.0.2490.86 e Firefox 42.0. Perché succede? Ho pensato che then() e catch() possono essere concatenati più volte?

+0

possibile duplicato di [Promesse concatenate che non passano al rifiuto] (http://stackoverflow.com/q/16371129/1048572) – Bergi

risposta

7

proprio come nel codice sincrono:

try { 
    throw new Error(); 
} catch(e) { 
    console.log("Caught"); 
} 
console.log("This still runs"); 

codice che viene eseguito dopo l'eccezione è stata gestita verrà eseguito - questo è perché eccezioni sono un meccanismo di recupero degli errori. Aggiungendo tale cattura hai segnalato che l'errore è stato gestito. Nel caso sincrona gestiamo questo rethrowing:

try { 
    throw new Error(); 
} catch(e) { 
    console.log("Caught"); 
    throw e; 
} 
console.log("This will not run, still in error"); 

Promises funzionano in modo simile:

Promise.reject(Error()).catch(e => { 
     console.log("This runs"); 
     throw e; 
}).catch(e => { 
     console.log("This runs too"); 
     throw e; 
}); 

Come una punta - non rifiutano con non Error s come si perde un sacco di cose utili come pila significativo tracce.

2

Perché ciò accade? Ho pensato che quindi() e catch() possono essere ripetuti più volte?

@Benjamin è giusto, +1, ma per dirla in un altro modo, queste sono le regole: metodi

  • Se si aggiungono then più volte, si concatenano che dovrebbero essere chiamati in sequenza , fino a quando non viene lanciata un'eccezione. Eccezioni nella catena then devono essere gestite da catch dichiarate dopo lo then. Se non c'è catch dopo il then, verrà generato questo errore: Uncaught (in promise) Error(…).
  • Se si aggiunge catch più volte, si concatenano i metodi da chiamare quando qualcosa va storto (nelle funzioni then precedenti). Tuttavia, il secondo catch nella catena verrà chiamato solo se il primo rigetterà l'eccezione e così via.
  • Quando viene attivato catch, la catena riprende il successivo then dichiarato dopo catch.