Eu dei uma olhada no FAQ de promessa de pássaro azul , no qual ele menciona que .then(success, fail)
é um antipadrão . Não entendo bem sua explicação quanto à tentativa e captura. O que há de errado nisso?
some_promise_call()
.then(function(res) { logger.log(res) }, function(err) { logger.log(err) })
Parece que o exemplo está sugerindo o seguinte como o caminho correto.
some_promise_call()
.then(function(res) { logger.log(res) })
.catch(function(err) { logger.log(err) })
Qual é a diferença?
javascript
node.js
promise
bluebird
user2127480
fonte
fonte
then().catch()
é mais legível, pois você não precisa procurar vírgula e investigar se esse retorno de chamada é para êxito ou falha na ramificação..catch
, não sabe qual etapa causou o problema - dentro da últimathen
ou em outro lugar da cadeia de promessas. Portanto, ele tem sua própria desvantagem.some_promise_call() .then(function fulfilled(res) { logger.log(res) }, function rejected(err) { logger.log(err) })
Respostas:
A
.then()
chamada retornará uma promessa que será rejeitada caso o retorno de chamada gere um erro. Isso significa que, quando seu sucessologger
falhar, o erro será passado para o.catch()
retorno de chamada a seguir , mas não para ofail
retorno de chamada que acompanha o mesmosuccess
.Aqui está um diagrama de fluxo de controle :
Para expressá-lo em código síncrono:
O segundo
log
(que é como o primeiro argumento.then()
) será executado apenas no caso de nenhuma exceção acontecer. O bloco rotulado eabreak
declaração sentir um pouco estranho, este é realmente o que python temtry-except-else
para (leitura recomendada!).O
catch
criador de logs também tratará exceções da chamada do registrador de sucesso.Tanto pela diferença.
O argumento é que geralmente você deseja capturar erros em todas as etapas do processamento e que não deve usá-lo em cadeias. A expectativa é que você tenha apenas um manipulador final que lide com todos os erros - enquanto, quando você usa o "antipadrão", os erros em alguns dos retornos de chamada não são tratados.
No entanto, esse padrão é realmente muito útil: quando você deseja lidar com erros que ocorreram exatamente nesta etapa e deseja fazer algo completamente diferente quando nenhum erro ocorreu - ou seja, quando o erro é irrecuperável. Esteja ciente de que isso está ramificando seu fluxo de controle. Claro, isso às vezes é desejado.
Que você teve que repetir seu retorno de chamada. Você prefere
Você também pode considerar usar
.finally()
isso.fonte
.catch
vai detectar erros, mesmo dentro da função sucesso .. Pessoalmente, acho isso extremamente errado, como você acabar com um ponto erro de entrada, que pode receber vários erros de várias ações, mas esse é o meu problema. De qualquer forma - obrigado pela informação! Você não tem alguma ferramenta de comunicação on-line que deseja compartilhar para que eu possa pedir mais algumas coisas? : PPromise
mecânico importante neste site..done()
não faz parte do padrão, é? Pelo menos o MDN não lista esse método. Isso ajudaria.done
é uma coisa do Bluebird que foi basicamente descontinuada pelathen
detecção de rejeição sem tratamento.Os dois não são completamente idênticos. A diferença é que o primeiro exemplo não captura uma exceção lançada em seu
success
manipulador. Portanto, se o seu método retornar apenas promessas resolvidas, como geralmente é o caso, você precisará de umcatch
manipulador à direita (ou outrothen
com umsuccess
parâmetro vazio ). Claro, pode ser que seuthen
manipulador não faça nada que possa falhar potencialmente; nesse caso, usar um parâmetro de 2then
pode ser bom.Mas acredito que o ponto do texto ao qual você vinculou
then
é o mais útil contra os retornos de chamada em sua capacidade de encadear várias etapas assíncronas, e quando você realmente faz isso, a forma de 2 parâmetros dethen
sutilmente não se comporta exatamente como o esperado , pela razão acima. É particularmente contra-intuitivo quando usado no meio da cadeia.Como alguém que fez um monte de coisas assíncronas complexas e esbarrou em cantos como esse mais do que gostaria de admitir, eu realmente recomendo evitar esse antipadrão e seguir a abordagem de manipulador separado.
fonte
Observando as vantagens e desvantagens de ambos, podemos fazer um palpite calculado sobre o que é apropriado para a situação. Estas são as duas principais abordagens para implementar promessas. Ambos têm suas vantagens e menos
Vantagens
Desvantagens
Vantagens
Desvantagens
catch
se desejar manipular erros gerados pelo retorno de chamada bem-sucedidofonte
Explique simples:
No ES2018
que significa:
é igual a
fonte
Usar
.then().catch()
permite ativar o Encadeamento de promessa, necessário para realizar um fluxo de trabalho. Pode ser necessário ler algumas informações do banco de dados, depois passar para uma API assíncrona e manipular a resposta. Você pode enviar a resposta de volta ao banco de dados. Lidar com todos esses fluxos de trabalho com o seu conceito é factível, mas é muito difícil de gerenciar. A melhor solução será athen().then().then().then().catch()
que recebe todos os erros em apenas uma captura e permite manter a manutenção do código.fonte
Usando
then()
ecatch()
ajudando a cadeia de sucesso e falha manipulador na promessa.catch()
trabalha sob promessa devolvida porthen()
. Ele lida com,then()
não lida com isso.)1. let promiseRef: Promise = this. aTimetakingTask (false); 2. promiseRef 3. .then( 4. (result) => { 5. /* successfully, resolved promise. 6. Work on data here */ 7. }, 8. (error) => console.log(error) 9. ) 10. .catch( (e) => { 11. /* successfully, resolved promise. 12. Work on data here */ 13. });
Faz sentido porque a promessa retornada por
then()
não tem um erro se um retorno de chamada está cuidando disso.fonte
catch
retorno de chamada parece errada.Em vez de palavras, bom exemplo. Código a seguir (se a primeira promessa for resolvida):
é idêntico a:
Mas com a primeira promessa rejeitada, isso não é idêntico:
fonte