È possibile utilizzare la maggior parte sia in questo caso (con una differenza comportamento). Il primo è la funzionalità standard di promessa e funzionerà con qualsiasi libreria di promessa.
Promise.try()
è una funzionalità specificatamente implementata dalla libreria Bluebird e non fa parte di alcun processo standard di cui sono a conoscenza.
Il motivo per utilizzare Promise.try()
è se si dispone di una funzione che restituisce una promessa, ma il codice che genera tale promessa potrebbe anche causare un'eccezione sincrona. Dal momento che quell'eccezione non è all'interno di alcun gestore di promesse, avresti un mix di gestione degli errori. Alcuni percorsi di esecuzione del codice potrebbero causare la restituzione di una promessa che sarebbe risolta o rifiutata e altri percorsi di esecuzione del codice potrebbero generare un'eccezione. Per codificare questo in modo sicuro, dovresti entrambi rispondere alla promessa e mettere un blocco try/catch attorno al codice che diventa ingombrante.
Promise.try()
è semplicemente un mezzo per rilevare automaticamente eventuali eccezioni e trasformarle in un rifiuto (simile a ciò che accade nei gestori .then()
).
Nei due casi, Promise.try()
non è vantaggioso in questo modo perché la richiamata new Promise()
intercetta già eccezioni e le trasforma in rifiuti in modo che la funzionalità sia già stata eseguita per voi. Si può vedere che ha dimostrato qui: http://jsfiddle.net/jfriend00/wLov9844/
Il doc Bluebird offre questo esempio che mostra il beneficio più chiaramente:
function getUserById(id) {
return Promise.try(function() {
if (typeof id !== "number") {
// Courtesy of Promise.try() this exception will be turned
// into a returned promise that is rejected with the
// exception as the reason
throw new Error("id must be a number");
}
return db.getUserById(id);
});
}
getUserById().then(successFn, errFn);
L'uso di Promise.try()
qui fa in modo che getUserById()
sarà sempre tornare una promessa, anche se il il codice all'interno di quel metodo genera un'eccezione in modo sincrono. Questo semplifica l'utilizzo di getUserById()
in quanto è sempre possibile rispondere alla promessa e non è necessario utilizzare il proprio gestore di eccezioni attorno ad esso.
Senza Promise.try()
, è possibile codificare la stessa cosa da soli come questo (per catturare tutte le eccezioni possibili sincrone all'interno della funzione):
function getUserById(id) {
try {
if (typeof id !== "number") {
throw new Error("id must be a number");
}
return db.getUserById(id);
} catch(e) {
return Promise.reject(e);
}
}
getUserById().then(successFn, errFn);
Oppure, si potrebbe codice in questo modo:
function getUserById(id) {
if (typeof id !== "number") {
throw new Error("id must be a number");
}
return db.getUserById(id);
}
try {
getUserById().then(successFn, errFn);
} catch(e) {
errFn(e);
}
Presumibilmente, è possibile vedere come Promise.try()
può semplificare le cose in alcune circostanze.
FYI, nel tuo primo esempio, stai usando una sintassi non valida.È possibile farlo:
reject(throw new Error('error'));
Sto assumendo quello che volevi dire era questo:
reject(new Error('error'));
Anche se non credo che questo è davvero quello che stavi chiedendo circa, sarà anche Promise.try()
restituire automaticamente una promessa risolta se non si restituisce una promessa da soli. Poiché un percorso del primo esempio non viene risolto o rifiutato, ciò causerà una differenza nei due esempi.
collegato in modo approssimativo: [Promise.reject vs throw error] (http://stackoverflow.com/q/28703241/1048572). Non dovresti usare il costruttore 'new Promise' a meno che tu non stia facendo qualcosa in modo asincrono. L'approccio corretto qui sarebbe quello di restituire Promise.reject (...) (o usare 'Promise.try' /' Promise.method'). – Bergi