Entendendo promessas no Node.js

147

Pelo que entendi, há três maneiras de chamar código assíncrono:

  1. Eventos, por exemplo request.on("event", callback);
  2. Retornos de chamada, por exemplo fs.open(path, flags, mode, callback);
  3. Promessas

Encontrei a biblioteca de promessas de nós, mas não a entendo.

Alguém poderia explicar quais são as promessas e por que devo usá-las?

Além disso, por que ele foi removido do Node.js.

ajsie
fonte
Este artigo explica muito bem. Quando se trata de uma implementação utilizável no node.js, dê uma olhada no Futures
Sean Kinsey
Aqui está uma ótima série que eu usei para criar minha própria classe de promessas: Vamos criar uma estrutura: promessas Aqui está um vídeo sobre o jQuery adiado
Tom Winter

Respostas:

91

As promessas no node.js prometeram fazer algum trabalho e, em seguida, tiveram retornos de chamada separados que seriam executados para obter êxito e falha, além de lidar com tempos limite. Outra maneira de pensar nas promessas no node.js era que eles eram emissores que podiam emitir apenas dois eventos: sucesso e erro.

O interessante das promessas é que você pode combiná-las em cadeias de dependência (faça a Promessa C somente quando a Promessa A e a Promessa B estiverem concluídas).

Ao removê-los do core node.js, criou a possibilidade de construir módulos com diferentes implementações de promessas que podem ficar no topo do core. Alguns deles são promessa de nó e futuros .

Paul Robinson
fonte
10
@weng Não, não é.
Ivo Wetzel
98

Como essa pergunta ainda tem muitos pontos de vista (como o meu), eu gostaria de salientar que:

  1. A promessa do nó parece um pouco morta para mim (a última confirmação ocorreu há cerca de um ano) e quase não contém testes.
  2. o módulo de futuros parece muito inchado para mim e está mal documentado (e acho que as convenções de nomenclatura são ruins)
  3. O melhor caminho a seguir parece ser a estrutura q , que é ativa e bem documentada.
enyo
fonte
9
Verifique também este github.com/medikoo/deferred , Q é um dos primeiros e é definitivamente a inspiração para muitas implementações que apareceram depois, mas infelizmente é muito lento e muito "teórico" em algumas partes, não funciona bem com algumas cenários do mundo real
Mariusz Nowak
Eu daria uma olhada neste vídeo sob promessas de um dos criadores do RSVP.js youtube.com/…
runspired
23
Atualização de 2014 - o bluebird é de longe o mais rápido e o que possui as melhores habilidades de depuração atualmente.
Benjamin Gruenbaum 04/04
19

Uma promessa é uma "coisa" que representa os resultados "eventuais" de uma operação, por assim dizer. O ponto a ser observado aqui é que ele abstrai os detalhes de quando algo acontece e permite que você se concentre no que deve acontecer depois que algo acontecer. Isso resultará em um código limpo e sustentável, onde, em vez de ter um retorno de chamada dentro de um retorno de chamada, seu código será parecido com:

 var request = new Promise(function(resolve, reject) {
   //do an ajax call here. or a database request or whatever.
   //depending on its results, either call resolve(value) or reject(error)
   //where value is the thing which the operation's successful execution returns and
   //error is the thing which the operation's failure returns.
 });

 request.then(function successHandler(result) {
   //do something with the result
 }, function failureHandler(error) {
  //handle
 });

As especificações das promessas afirmam que uma promessa é

then

O método deve retornar uma nova promessa que é cumprida quando o retorno de chamada successHandler ou failHandler especificado é concluído. Isso significa que você pode encadear promessas quando tiver um conjunto de tarefas assíncronas que precisam ser executadas e ter certeza de que o seqüenciamento de operações é garantido como se você tivesse usado retornos de chamada. Portanto, em vez de passar um retorno de chamada para dentro de um retorno de chamada, o código com promessas encadeadas se parece com:

var doStuff = firstAsyncFunction(url) {
                return new Promise(function(resolve, reject) {
                       $.ajax({
                        url: url,
                        success: function(data) {
                            resolve(data);
                        },
                        error: function(err) {
                             reject(err); 
                        } 
                  });
               };
doStuff
  .then(secondAsyncFunction) //returns a promise
  .then(thirdAsyncFunction); //returns a promise

Para saber mais sobre as promessas e por que elas são super legais, confira o blog de Domenic: http://domenic.me/2012/10/14/youre-missing-the-point-of-promises/

Hrishi
fonte
12

Este novo tutorial sobre promessas do autor do PouchDB é provavelmente o melhor que eu já vi em qualquer lugar. Ele cobre sabiamente os erros clássicos de novatos, mostrando os padrões de uso corretos e até alguns anti-padrões que ainda são comumente usados ​​- mesmo em outros tutoriais !!

Aproveitar!

PS: Eu não respondi algumas outras partes desta pergunta, pois elas foram bem cobertas por outras.

Tony O'Hagan
fonte
Meu único pedido de desculpas por isso é forçar você a ler humor no final do erro avançado nº 4.
Tony O'Hagan
De fato, o código no tutorial que eles afirmam ser um antipadrão precisa do aninhamento do loop e da condição e não pode ser tão facilmente achatado como sugerem.
Bergi 25/05
O erro avançado nº 4 também pode ser resolvido usando um número muito maior de abordagens diferentes, consulte Como acesso os resultados das promessas anteriores em uma cadeia .then ()? (o padrão de fechamento que eles sugerem não parece ser muito popular).
Bergi 25/05
Acho que essa resposta somente de link deveria ter sido um comentário. Coloque pelo menos os pontos principais desse artigo em sua resposta aqui.
Bergi 25/05
7

Mike Taulty tem uma série de vídeos , cada um com menos de dez minutos, descrevendo como a biblioteca WinJS Promise funciona.

Esses vídeos são bastante informativos e Mike consegue mostrar o poder da API Promise com alguns exemplos de código bem escolhidos.

var twitterUrl = "http://search.twitter.com/search.json?q=windows";
var promise = WinJS.xhr({ url: twitterUrl });

 promise = promise.then(
     function (xhr) {
     },
     function (xhr) {
         // handle error
     });

O tratamento de como as exceções são tratadas é particularmente bom.

Apesar das referências do WinJs, esta é uma série de vídeos de interesse geral, porque a API do Promise é amplamente semelhante em muitas implementações.

Responda Por Favor é uma implementação leve do Promise que passa no conjunto de testes Promise / A +. Eu gosto bastante da API, porque é semelhante em estilo à interface do WinJS.

Atualização abr-2014

Aliás, a biblioteca WinJS agora é de código aberto .

Noel Abrahams
fonte
1
+1. Este é o primeiro exemplo que eu vi que faz sentido para mim e é intuitivo de usar. De alguma forma, meu cérebro não pode analisar todo o deferredse resolvee deferred.promise.thene predefinir de promiseActionsna popular documentação da biblioteca Q. Alguma chance de você saber algo tão simples sobre o Node.js ?
Redsandro 16/01
1
@noel obrigado por compartilhar o link acima, é uma excelente série introdutória de promessas, e eu concordo que as especificidades do WinJS são irrelevantes, pois a abordagem / tópico geral é universal.
Arcseldon #
Belo exemplo. Também eu fixa-se o seu primeiro link que estava morto
stonedauwg
5

Outra vantagem das promessas é que o tratamento de erros e a ativação e captura de exceções são muito melhores do que tentar lidar com isso com retornos de chamada.

A biblioteca bluebird implementa promessas e fornece ótimos rastreamentos de pilha longa, é muito rápida e alerta sobre erros não detectados. Também é mais rápido e usa menos memória do que as outras bibliotecas promissoras, de acordo com http://bluebirdjs.com/docs/benchmarks.html

llambda
fonte
4

O que exatamente é uma promessa?

Uma promessa é simplesmente um objeto que representa o resultado de uma operação assíncrona. Uma promessa pode estar em qualquer um dos três estados a seguir:

pendente :: Este é o estado inicial, significa que a promessa não é cumprida nem rejeitada.

cumprida : significa que a promessa foi cumprida, significa que o valor representado pela promessa está pronto para ser usado.

rejeitado :: Isso significa que as operações falharam e, portanto, não podem cumprir a promessa. Além dos estados, existem três entidades importantes associadas a promessas que realmente precisamos entender

  1. executor function :: executor function define a operação assíncrona que precisa ser executada e cujo resultado é representado pela promessa. Inicia a execução assim que o objeto de promessa é inicializado.

  2. resolve :: resolve é um parâmetro passado para a função executora e, caso o executor seja executado com êxito, essa resolução será chamada passando o resultado.

  3. Reject :: Reject é outro parâmetro passado para a função executora e é usado quando a função executora falha. O motivo da falha pode ser passado para a rejeição.

Portanto, sempre que criamos um objeto de promessa, devemos fornecer Executor, Resolve e Reject.

Referência :: Promessas

Rishabh.IO
fonte
0

Também estive procurando promessas no node.js recentemente. Até o momento, o when.js parece ser o caminho a seguir devido à sua velocidade e uso de recursos, mas a documentação do q.js me deu um entendimento muito melhor. Portanto, use when.js, mas o q.js documenta para entender o assunto.

A partir dos q.js leia-me no github:

Se uma função não puder retornar um valor ou lançar uma exceção sem bloquear, poderá retornar uma promessa. Uma promessa é um objeto que representa o valor de retorno ou a exceção lançada que a função pode eventualmente fornecer. Uma promessa também pode ser usada como proxy para um objeto remoto para superar a latência.

Andrew Roberts
fonte
0

O objeto Promise representa a conclusão ou falha de uma operação assíncrona.

Portanto, para implementar uma promessa, você precisa de duas partes:

1. Criando Promessa:

O construtor da promessa aceita uma função chamada executor que possui 2 parâmetros para resolver e rejeitar.

function example(){
   return new Promise (function(resolve , reject){   //return promise object
      if(success){
         resolve('success');  //onFullfiled
      }else{
         reject('error');     //onRejected
      }
   })
}

2. Promessa de Manuseio:

O objeto Promise possui 3 métodos para manipular objetos Promise: -

1.Promise.prototype.catch (onRejected)

2.Promise.prototype.then (onFullfiled)

3.Promise.prototype.finally (onFullfiled, onRejected)

example.then((data) =>{
  //handles resolved data
  console.log(data); //prints success     
}).catch((err) => {
  //handles rejected error 
  console.log(err);  //prints error
})
Pavneet Kaur
fonte