Em tutoriais anteriores, você teria visto funções de retorno de chamada que são usadas para eventos assíncronos. Mas às vezes as funções de retorno de chamada podem se tornar um pesadelo quando começam a se tornar aninhadas e o programa começa a se tornar longo e complexo.
Neste tutorial, você aprenderá-
- O que são promessas?
- Chamadas de retorno para promessas
- Lidando com promessas aninhadas
- Criação de uma promessa personalizada
O que são promessas?
Antes de começarmos com as promessas, vamos primeiro revisitar o que são funções de "retorno de chamada" no Node.js. Vimos muito essas funções de retorno de chamada nos capítulos anteriores, portanto, vamos examinar rapidamente uma delas.
O exemplo abaixo mostra um fragmento de código, que é usado para se conectar a um banco de dados MongoDB e executar uma operação de atualização em um dos registros no banco de dados.
-
No código acima, a parte da função (err, db) é conhecida como a declaração de uma função anônima ou de retorno de chamada. Quando o MongoClient cria uma conexão com o banco de dados MongoDB, ele retornará à função de retorno de chamada assim que a operação de conexão for concluída. De certa forma, as operações de conexão acontecem em segundo plano e, quando concluídas, chama nossa função de retorno de chamada. Lembre-se de que este é um dos pontos-chave do Node.js para permitir que muitas operações ocorram simultaneamente e, portanto, não impedir que qualquer usuário execute uma operação.
-
O segundo bloco de código é o que é executado quando a função de retorno de chamada é realmente chamada. A função de retorno de chamada apenas atualiza um registro em nosso banco de dados MongoDB.
Então, o que é uma promessa? Bem, uma promessa é apenas um aprimoramento das funções de retorno de chamada no Node.js. Durante o ciclo de vida de desenvolvimento, pode haver uma instância em que você precise aninhar várias funções de retorno de chamada juntas. Isso pode ficar um pouco confuso e difícil de manter em um determinado momento. Em suma, uma promessa é um aprimoramento dos retornos de chamada que visa aliviar esses problemas.
A sintaxe básica de uma promessa é mostrada abaixo;
var promise = doSomethingAync()promise.then(onFulfilled, onRejected)
- "doSomethingAync" é qualquer retorno de chamada ou função assíncrona que faz algum tipo de processamento.
- Desta vez, ao definir o retorno de chamada, existe um valor que é devolvido denominado "promessa".
- Quando uma promessa é retornada, ela pode ter 2 saídas. Isso é definido pela 'cláusula then'. A operação pode ser um sucesso, o que é indicado pelo parâmetro 'onFulfilled'. Ou pode haver um erro denotado pelo parâmetro 'onRejected'.
Nota: Portanto, o aspecto principal de uma promessa é o valor de retorno. Não há conceito de valor de retorno ao trabalhar com retornos de chamada normais em Node.js. Por causa do valor de retorno, temos mais controle de como a função de retorno de chamada pode ser definida.
No próximo tópico, veremos um exemplo de promessas e como elas se beneficiam dos retornos de chamada.
Chamadas de retorno para promessas
Agora vamos dar uma olhada em um exemplo de como podemos usar "promessas" em um aplicativo Node.js. Para usar promessas em um aplicativo Node.js, o módulo 'promessa' deve primeiro ser baixado e instalado.
Em seguida, modificaremos nosso código conforme mostrado abaixo, que atualiza um Employeename na coleção 'Employee' usando promessas.
Etapa 1) Instalação dos módulos NPM
Para usar Promises de dentro de um aplicativo Node JS, o módulo de promessa é necessário. Para instalar o módulo de promessa, execute o comando abaixo
promessa de instalação npm
Etapa 2) Modifique o código para incluir promessas
var Promise = require('promise');var MongoClient = require('mongodb').MongoClient;var url = 'mongodb://localhost/EmployeeDB';MongoClient.connect(url).then(function(err, db) {db.collection('Employee').updateOne({"EmployeeName": "Martin"}, {$set: {"EmployeeName": "Mohan"}});});
Explicação do código: -
- A primeira parte é incluir o módulo 'promessa' que nos permitirá usar a funcionalidade de promessa em nosso código.
- Agora podemos anexar a função 'then' à nossa função MongoClient.connect. Então, o que isso significa é que, quando a conexão é estabelecida com o banco de dados, precisamos executar o trecho de código definido a seguir.
- Finalmente, definimos nosso trecho de código que faz o trabalho de atualizar EmployeeName do funcionário com o nome de "Martin" para "Mohan".
Observação:-
Se você verificar agora o conteúdo de seu banco de dados MongoDB, descobrirá que, se existir um registro com EmployeeName de "Martin", ele será atualizado para "Mohan".
Para verificar se os dados foram inseridos corretamente no banco de dados, você precisa executar os seguintes comandos no MongoDB
- Use EmployeeDB
- db.Employee.find ({EmployeeName: Mohan})
A primeira instrução garante que você esteja conectado ao banco de dados EmployeeDb. A segunda declaração procura o registro que tem o nome do funcionário "Mohan".
Lidando com promessas aninhadas
Ao definir promessas, é necessário observar que o próprio método "then" retorna uma promessa. Então, de certa forma, as promessas podem ser aninhadas ou acorrentadas umas às outras.
No exemplo abaixo, usamos o encadeamento para definir 2 funções de retorno de chamada, sendo que ambas inserem um registro no banco de dados MongoDB.
( Observação : o encadeamento é um conceito usado para vincular a execução de métodos uns aos outros. Suponha que se seu aplicativo tivesse 2 métodos chamados 'método A' e 'método B.' então você encadearia a execução de tal forma que 'métodoB' fosse chamado diretamente após 'métodoA'.)
O principal ponto a ser observado neste exemplo é que o código se torna mais limpo, legível e sustentável usando promessas aninhadas.
var Promise = require('promise');var MongoClient = require('mongodb').MongoClient;var url = 'mongodb://localhost/EmployeeDB';MongoClient.connect(url).then(function(db) {db.collection('Employee').insertOne({Employeeid: 4,EmployeeName: "NewEmployee"}).then(function(db1) {db1.collection('Employee').insertOne({Employeeid: 5,EmployeeName: "NewEmployee1"})})});
Explicação do código: -
- Estamos agora definindo 2 cláusulas "then" que são executadas uma após a outra. Na primeira cláusula then, estamos passando o parâmetro 'db' que contém nossa conexão de banco de dados. Em seguida, estamos usando a propriedade de coleção da conexão 'db' para inserir registros na coleção 'Funcionário'. O método 'insertOne' é usado para inserir o documento real na coleção Employee.
- Então, estamos usando a cláusula 2 nd then também para inserir outro registro no banco de dados.
Se você verificar agora o conteúdo de seu banco de dados MongoDB, encontrará os 2 registros inseridos no banco de dados MongoDB.
Criação de uma promessa personalizada
Uma promessa personalizada pode ser criada usando um módulo de nó chamado 'q.' A biblioteca 'q' precisa ser baixada e instalada usando o gerenciador de pacotes do nó. Depois de usar a biblioteca 'q', o método "denodeify" pode ser chamado, o que fará com que qualquer função se torne uma função que retorna uma promessa.
No exemplo abaixo, criaremos uma função simples chamada "Adicionar" que adicionará 2 números. Vamos converter esta função em uma função para retornar uma promessa.
Feito isso, usaremos a promessa retornada pela função Add para exibir uma mensagem no console.log.
Vamos seguir as etapas abaixo para criar nossa função personalizada para retornar uma promessa.
Etapa 1) Instalação dos módulos NPM
Para usar 'q' de dentro de um aplicativo Node JS, o módulo 'q' é necessário. Para instalar o módulo 'q', execute o comando abaixo
npm instalar q
Etapa 2) Defina o código a seguir, que será usado para criar a promessa personalizada.
Explicação do código: -
- O primeiro bit é incluir a biblioteca 'q' usando a palavra-chave require. Usando esta biblioteca, seremos capazes de definir qualquer função para retornar um retorno de chamada.
- Estamos criando uma função chamada Add que adicionará 2 números definidos nas variáveis a e b. A soma desses valores será armazenada na variável c.
- Estamos então usando a biblioteca q para denodeificar (o método usado para converter qualquer função em uma função que retornaria uma promessa) nossa função Add ou, de outra forma, converter nossa função Add em uma função que retorne uma promessa.
- Agora chamamos nossa função "Adicionar" e podemos obter um valor de promessa de retorno por causa da etapa anterior que executamos de denodeificar a função Adicionar.
- A palavra-chave 'then' é usada para especificar que, se a função for executada com sucesso, exiba a string "Função de adição concluída" no console.log.
Quando o código acima for executado, a saída "Função de adição concluída" será exibida no console.log, conforme mostrado abaixo.
Resumo
- Usar funções de retorno de chamada em Node.js tem suas desvantagens. Às vezes, durante o processo de desenvolvimento, o uso aninhado de funções de retorno de chamada pode tornar o código mais confuso e difícil de manter.
- A maioria dos problemas com funções de retorno de chamada aninhadas pode ser atenuada com o uso de promessas e geradores em node.js
- Uma promessa é um valor retornado por uma função assíncrona para indicar a conclusão do processamento realizado pela função assíncrona.
- As promessas podem ser aninhadas umas nas outras para fazer o código parecer melhor e mais fácil de manter quando uma função assíncrona precisa ser chamada após outra função assíncrona