Tutorial de promessa do Node.js
Em tutoriais anteriores, você deve ter visto funções de retorno de chamada usadas para eventos assíncronos. Mas às vezes as funções de retorno de chamada podem se tornar um pesadelo quando começam a ficar aninhadas e o programa começa a ficar longo e complexo.
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, então vamos examinar rapidamente uma delas.
O exemplo abaixo mostra um trecho de código, que é usado para conectar-se a um MongoDB banco de dados e execute uma operação de atualização em um dos registros do banco de dados.
- No código acima, a parte da function(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 MongoDB banco de dados, ele retornará à função de retorno de chamada assim que a operação de conexão for concluída. Então, de certa forma, as operações de conexão acontecem em segundo plano e, quando terminam, chama nossa função de retorno de chamada. Lembre-se que este é um dos pontos-chave do Node.js para permitir que muitas operações aconteçam simultaneamente e assim não impedir que nenhum 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 MongoDB base de dados.
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ê precisará aninhar várias funções de retorno de chamada. Isso pode ficar meio confuso e difícil de manter em um determinado momento. Resumindo, uma promessa é um aprimoramento nos 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, há um valor que é retornado 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, indicado pelo parâmetro 'onFulfilled'. Ou pode haver um erro indicado 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 sobre 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 callbacks.
Retornos de chamada para promessas
Agora vamos ver um exemplo de como podemos usar “promessas” em uma aplicação Node.js. Para usar promessas em uma aplicação 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.
Passo 1) Instalando os Módulos NPM
Para usar Promises em 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
Passo 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 faz é que, quando a conexão com o banco de dados for estabelecida, precisamos executar o trecho de código definido a seguir.
- Por fim, definimos nosso trecho de código que faz o trabalho de atualizar EmployeeName do funcionário com o nome “Martin” para “Mohan”.
Nota:-
Se você verificar agora o conteúdo do seu MongoDB banco de dados, você 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 em MongoDB
- Usar EmployeeDB
- db.Employee.find({NomedoFuncionário:Mohan})
A primeira instrução garante que você esteja conectado ao banco de dados EmployeeDb. O segundo extrato busca o registro que contém o nome do funcionário “Mohan”.
Lidando com promessas aninhadas
Ao definir promessas, é necessário observar que o próprio método “então” retorna uma promessa. Então, de certa forma, as promessas podem ser aninhadas ou encadeadas umas às outras.
No exemplo abaixo, usamos encadeamento para definir 2 funções de retorno de chamada, ambas inserem um registro no MongoDB base de dados.
(Note: Encadeamento é um conceito usado para vincular a execução de métodos entre si. Suponha que seu aplicativo tivesse 2 métodos chamados 'methodA' e 'methodB.' E a lógica era tal que 'métodoB' deveria ser chamado depois de 'métodoA', então você encadearia a execução de tal forma que 'métodoB' fosse chamado diretamente após 'métodoA'.)
A principal coisa a ser observada neste exemplo é que o código se torna mais limpo, legível e de fácil manutenção 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: -
- Agora estamos 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 com o banco de dados. Estamos então usando a propriedade de coleção da conexão 'db' para inserir registros na coleção 'Employee'. O método 'insertOne' é usado para inserir o documento real na coleção Employee.
- Estamos então usando o 2nd cláusula then também para inserir outro registro no banco de dados.
Se você verificar agora o conteúdo do seu MongoDB banco de dados, você encontrará os 2 registros inseridos no MongoDB base de dados.
Criando 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 irá somar 2 números. Converteremos 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.
Passo 1) Instalando os Módulos NPM
Para usar 'q' em um aplicativo Node JS, o módulo 'q' é necessário. Para instalar o módulo 'q', execute o comando abaixo
npm instalar q
Passo 2) Defina o código a seguir que será usado para criar a promessa personalizada.
Explicação do código: -
- A primeira parte é incluir a biblioteca 'q' usando a palavra-chave require. Ao usar esta biblioteca, poderemos definir qualquer função para retornar um retorno de chamada.
- Estamos criando uma função chamada Add que irá somar 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 retorna uma promessa.
- Agora chamamos nossa função “Adicionar” e podemos obter um valor de promessa de retorno por causa da etapa anterior que realizamos 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
- O uso de funções de retorno de chamada no 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 podem ser mitigadas 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 precisar ser chamada após outra função assíncrona