Encontrei o seguinte código em um tutorial:
promise.then(function(result){
//some code
}).catch(function(error) {
throw(error);
});
Estou um pouco confuso: a chamada catch realiza alguma coisa? Parece-me que não tem nenhum efeito, pois simplesmente lança o mesmo erro que foi detectado. Eu baseio isso em como funciona um try / catch regular.
javascript
promise
Tyler Durden
fonte
fonte
try { ... }catch(error){ throw new Error("something went wrong") }
. Ou para mostrar que Promessas e Erros são compatíveis (pelo menos dessa forma) . Mas em sua implementação atual é simplesmente estúpido. Você está certo, ele não faz nada e nem mesmo é como um gancho que você adicionaria em OOP para permitir sobrescrevê-lo em uma classe herdada. Eu adicionaria o catch-block assim que fizer algo, mas não assim, não apenas como um marcador de posição.Respostas:
Não há sentido em pegar e jogar nu como você mostra. Ele não faz nada útil, exceto adicionar código e execução lenta. Então, se você for
.catch()
e relançar, deve haver algo que você deseja fazer no.catch()
, caso contrário, você deve apenas remover o.catch()
inteiramente.O ponto usual para essa estrutura geral é quando você deseja executar algo no
.catch()
, como registrar o erro ou limpar algum estado (como fechar arquivos), mas deseja que a cadeia de promessa continue como rejeitada.promise.then(function(result){ //some code }).catch(function(error) { // log and rethrow console.log(error); throw error; });
Em um tutorial, pode estar lá apenas para mostrar às pessoas onde eles podem detectar erros ou para ensinar o conceito de como lidar com o erro e, em seguida, relançá-lo.
Algumas das razões úteis para captura e relançamento são as seguintes:
Mas, uma simples captura e relançamento do mesmo erro sem nenhum outro código no manipulador de captura não faz nada útil para a execução normal do código.
fonte
throw new Exception(periousException);
não saber se o javascript suporta erro aninhado, mas mesmo assim "log e lançar" é uma prática ruim..catch()
e lançar o mesmo erro dentro do catch, a menos que você faça ALGUMA COISA no.catch()
. Esse é o ponto desta resposta..finally()
pode ser muito útil para isso, mas às vezes os recursos já estão sendo cuidados no caminho de não erro, então.catch()
ainda é o lugar para fechá-los. Realmente depende da situação.Os métodos
.then()
e.catch()
retornam Promises e, se você lançar uma Exception em qualquer um dos manipuladores, a promessa retornada será rejeitada e a Exception será capturada no próximo manipulador de rejeição.No código a seguir, lançamos uma exceção no primeiro
.catch()
, que é capturada no segundo.catch()
:new Promise((resolve, reject) => { console.log('Initial'); resolve(); }) .then(() => { throw new Error('Something failed'); console.log('Do this'); // Never reached }) .catch(() => { console.log('Something failed'); throw new Error('Something failed again'); }) .catch((error) => { console.log('Final error : ', error.message); });
O segundo
.catch()
retorna um Promised que é cumprido, o.then()
manipulador pode ser chamado:new Promise((resolve, reject) => { console.log('Initial'); resolve(); }) .then(() => { throw new Error('Something failed'); console.log('Do this'); // Never reached }) .catch(() => { console.log('Something failed'); throw new Error('Something failed again'); }) .catch((error) => { console.log('Final error : ', error.message); }) .then(() => { console.log('Show this message whatever happened before'); });
Referência útil: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises#Chaining_after_a_catch
Espero que isto ajude!
fonte
Não há diferença importante se você deixar de fora
catch
chamada de método completamente de fora.A única coisa que adiciona é uma microtarefa extra, o que na prática significa que você notará a rejeição da promessa mais tarde do que no caso de uma promessa que falha sem o
catch
cláusula.O próximo snippet demonstra isso:
var p; // Case 1: with catch p = Promise.reject('my error 1') .catch(function(error) { throw(error); }); p.catch( error => console.log(error) ); // Case 2: without catch p = Promise.reject('my error 2'); p.catch( error => console.log(error) );
Observe como a segunda rejeição é relatada antes da primeira. Essa é a única diferença.
fonte
Portanto, parece que sua pergunta é: "Na cadeia de promessas, o que o
.catch()
método faz?"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/throw
A instrução throw "irá parar (as instruções após throw não serão executadas) e o controle será passado para o primeiro bloco catch na pilha de chamadas. Se nenhum bloco catch existir entre as funções do chamador, o programa será encerrado."
Na cadeia de promessa, o
.then()
método retornará algum tipo de bloco de dados. Este retorno do pedaço completará a promessa. O retorno bem-sucedido dos dados completa a promessa. Você pode pensar no.catch()
método da mesma maneira..catch()
no entanto, irá lidar com recuperações de dados malsucedidas. A declaração de lançamento completa a promessa. Ocasionalmente, você verá que os desenvolvedores usam o.catch((err) => {console.log(err))}
que também completaria a cadeia de promessa.fonte
Na verdade, você não precisa jogá-lo novamente, apenas deixe o Promise.catch vazio, caso contrário ele considerará como não manipulado a rejeição e, em seguida, envolverá o código em um try catch e detectará o erro automaticamente que está ocorrendo.
try{ promise.then(function(result){ //some code }).catch(function(error) { //no need for re throwing or any coding. but leave this as this otherwise it will consider as un handled }); }catch(e){ console.log(e); //error can handle in here }
fonte
Na cadeia de promessa, é melhor usar .catch
ex na função f2: .então (...). captura (e => rejeitar (e));
function f1() { return new Promise((resolve, reject) => { throw new Error('test'); }); } function f2() { return new Promise((resolve, reject) => { f1().then(value => { console.log('f1 ok ???'); }).catch(e => reject(e)); }); } function test1() { console.log('test1 - with try catch - look in F12'); try { f2().then(() => { // Uncaught (in promise) Error: test console.log('???'); }); } catch (e) { console.log('this error dont catched'); } } function test2() { console.log('test2 - without try or .catch - look in F12'); f2(); // Uncaught (in promise) Error: test } function test3() { console.log('test3 - with .catch'); f2().then(value => { console.log('??'); }).catch(e => { console.log(' now its ok, error ', e); }) } setTimeout(() => { test1(); setTimeout(() => { test2(); setTimeout(() => { test3(); }, 100); }, 100); }, 100);
fonte