En tutoriales anteriores, habría visto funciones de devolución de llamada que se utilizan para eventos asincrónicos. Pero a veces las funciones de devolución de llamada pueden convertirse en una pesadilla cuando comienzan a anidarse y el programa comienza a volverse largo y complejo.
En este tutorial, aprenderá:
- ¿Qué son las promesas?
- Devolución de llamada a promesas
- Lidiar con promesas anidadas
- Creando una promesa personalizada
¿Qué son las promesas?
Antes de comenzar con las promesas, revisemos primero las funciones de "devolución de llamada" en Node.js. Hemos visto muchas funciones de devolución de llamada en los capítulos anteriores, así que repasemos rápidamente una de ellas.
El siguiente ejemplo muestra un fragmento de código, que se utiliza para conectarse a una base de datos MongoDB y realizar una operación de actualización en uno de los registros de la base de datos.
-
En el código anterior, la parte de la función (err, db) se conoce como la declaración de una función anónima o de devolución de llamada. Cuando MongoClient crea una conexión a la base de datos MongoDB, volverá a la función de devolución de llamada una vez que se complete la operación de conexión. Entonces, en cierto sentido, las operaciones de conexión ocurren en segundo plano, y cuando se hace, llama a nuestra función de devolución de llamada. Recuerde que este es uno de los puntos clave de Node.js para permitir que sucedan muchas operaciones al mismo tiempo y así no bloquear a ningún usuario para que no realice una operación.
-
El segundo bloque de código es lo que se ejecuta cuando se llama realmente a la función de devolución de llamada. La función de devolución de llamada solo actualiza un registro en nuestra base de datos MongoDB.
Entonces, ¿qué es una promesa entonces? Bueno, una promesa es solo una mejora de las funciones de devolución de llamada en Node.js. Durante el ciclo de vida del desarrollo, puede haber una instancia en la que deba anidar varias funciones de devolución de llamada juntas. Esto puede volverse un poco complicado y difícil de mantener en un momento determinado. En resumen, una promesa es una mejora de las devoluciones de llamada que busca aliviar estos problemas.
La sintaxis básica de una promesa se muestra a continuación;
var promise = doSomethingAync()promise.then(onFulfilled, onRejected)
- "doSomethingAync" es cualquier devolución de llamada o función asincrónica que realiza algún tipo de procesamiento.
- Esta vez, al definir la devolución de llamada, hay un valor que se devuelve llamado "promesa".
- Cuando se devuelve una promesa, puede tener 2 salidas. Esto está definido por la 'cláusula entonces'. O la operación puede ser un éxito, lo que se indica con el parámetro 'onFuldered'. O puede tener un error que se indica con el parámetro 'onRejected'.
Nota: Entonces, el aspecto clave de una promesa es el valor de retorno. No existe un concepto de valor de retorno cuando se trabaja con devoluciones de llamada normales en Node.js. Debido al valor de retorno, tenemos más control sobre cómo se puede definir la función de devolución de llamada.
En el siguiente tema, veremos un ejemplo de promesas y cómo se benefician de las devoluciones de llamada.
Devolución de llamada a promesas
Ahora veamos un ejemplo de cómo podemos usar "promesas" desde dentro de una aplicación Node.js. Para utilizar promesas en una aplicación Node.js, primero se debe descargar e instalar el módulo 'promesa'.
Luego, modificaremos nuestro código como se muestra a continuación, que actualiza un nombre de empleado en la colección 'Empleado' mediante el uso de promesas.
Paso 1) Instalación de los módulos NPM
Para usar Promesas desde una aplicación Node JS, se requiere el módulo de promesa. Para instalar el módulo de promesa, ejecute el siguiente comando
promesa de instalación de npm
Paso 2) Modifique el código para incluir promesas
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"}});});
Explicación del código: -
- La primera parte es incluir el módulo de 'promesa' que nos permitirá usar la funcionalidad de promesa en nuestro código.
- Ahora podemos agregar la función 'entonces' a nuestra función MongoClient.connect. Entonces, lo que hace es que cuando se establece la conexión a la base de datos, necesitamos ejecutar el fragmento de código definido a partir de entonces.
- Finalmente, definimos nuestro fragmento de código que hace el trabajo de actualizar EmployeeName del empleado con el nombre de "Martin" a "Mohan".
Nota:-
Si ahora verifica el contenido de su base de datos MongoDB, encontrará que si existe un registro con EmployeeName de "Martin", se actualizará a "Mohan".
Para verificar que los datos se hayan insertado correctamente en la base de datos, debe ejecutar los siguientes comandos en MongoDB
- Utilice EmployeeDB
- db.Employee.find ({EmployeeName: Mohan})
La primera declaración asegura que está conectado a la base de datos EmployeeDb. La segunda instrucción busca el registro que tiene el nombre de empleado "Mohan".
Lidiar con promesas anidadas
Al definir las promesas, debe tenerse en cuenta que el método "entonces" en sí mismo devuelve una promesa. Entonces, en cierto sentido, las promesas se pueden anidar o encadenar entre sí.
En el siguiente ejemplo, usamos el encadenamiento para definir 2 funciones de devolución de llamada, las cuales insertan un registro en la base de datos MongoDB.
( Nota : El encadenamiento es un concepto que se utiliza para vincular la ejecución de métodos entre sí. Suponga que si su aplicación tuviera 2 métodos llamados 'métodoA' y 'métodoB'. Y la lógica era tal que 'métodoB' debería llamarse después de 'métodoA', luego encadenaría la ejecución de tal manera que 'métodoB' se llame directamente después de 'métodoA').
La clave a tener en cuenta en este ejemplo es que el código se vuelve más limpio, legible y fácil de mantener mediante el uso de promesas anidadas.
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"})})});
Explicación del código: -
- Ahora estamos definiendo 2 cláusulas "entonces" que se ejecutan una tras otra. En la primera cláusula, luego, estamos pasando el parámetro 'db' que contiene nuestra conexión a la base de datos. Entonces usamos la propiedad de colección de la conexión 'db' para insertar registros en la colección 'Empleado'. El método 'insertOne' se utiliza para insertar el documento real en la colección Employee.
- Entonces estamos usando la cláusula 2 nd then también para insertar otro registro en la base de datos.
Si ahora verifica el contenido de su base de datos MongoDB, encontrará los 2 registros insertados en la base de datos MongoDB.
Creando una promesa personalizada
Se puede crear una promesa personalizada utilizando un módulo de nodo llamado 'q'. La biblioteca 'q' debe descargarse e instalarse mediante el administrador de paquetes de nodos. Después de usar la biblioteca 'q', se puede llamar al método "denodeify", lo que hará que cualquier función se convierta en una función que devuelva una promesa.
En el siguiente ejemplo, crearemos una función simple llamada "Agregar" que agregará 2 números. Convertiremos esta función en una función para devolver una promesa.
Una vez hecho esto, usaremos la promesa devuelta por la función Agregar para mostrar un mensaje en el archivo console.log.
Sigamos los pasos a continuación para crear nuestra función personalizada para devolver una promesa.
Paso 1) Instalación de los módulos NPM
Para usar 'q' desde dentro de una aplicación Node JS, se requiere el módulo 'q'. Para instalar el módulo 'q', ejecute el siguiente comando
npm instalar q
Paso 2) Defina el siguiente código que se utilizará para crear la promesa personalizada.
Explicación del código: -
- El primer bit es incluir la biblioteca 'q' usando la palabra clave require. Al usar esta biblioteca, podremos definir cualquier función para devolver una devolución de llamada.
- Estamos creando una función llamada Agregar que agregará 2 números definidos en las variables ay b. La suma de estos valores se almacenará en la variable c.
- Luego estamos usando la biblioteca q para denodeificar (el método utilizado para convertir cualquier función en una función que devolvería una promesa) nuestra función Agregar o convertir nuestra función Agregar en una función que devuelve una promesa.
- Ahora llamamos a nuestra función "Agregar" y podemos obtener un valor de promesa de retorno debido al paso anterior que realizamos de denodeificar la función Agregar.
- La palabra clave 'entonces' se utiliza para especificar que si la función se ejecuta correctamente, se mostrará la cadena "Función de adición completada" en el archivo console.log.
Cuando se ejecuta el código anterior, la salida "Función de adición completada" se mostrará en el archivo console.log como se muestra a continuación.
Resumen
- El uso de funciones de devolución de llamada en Node.js tiene sus desventajas. A veces, durante el proceso de desarrollo, el uso anidado de funciones de devolución de llamada puede hacer que el código sea más complicado y difícil de mantener.
- La mayoría de los problemas con las funciones de devolución de llamada anidadas se pueden mitigar con el uso de promesas y generadores en node.js
- Una Promesa es un valor devuelto por una función asíncrona para indicar la finalización del procesamiento realizado por la función asíncrona.
- Las promesas se pueden anidar entre sí para hacer que el código se vea mejor y sea más fácil de mantener cuando una función asincrónica necesita ser llamada después de otra función asincrónica.