usar una trabajar promesas promesa platzi hacer ejecucion cuando controlar con como asincronia asincrona anidadas javascript node.js promise q bluebird

una - promesas javascript platzi



¿Todavía hay razones para usar bibliotecas de promesas como Q o BlueBird ahora que tenemos promesas de ES6? (1)

El viejo adagio dice que debes elegir la herramienta adecuada para el trabajo. Las promesas de ES6 proporcionan lo básico. Si todo lo que quiere o necesita es lo básico, entonces eso debería / podría funcionar bien para usted. Pero, hay más herramientas en el contenedor de herramientas que solo los básicos y hay situaciones en las que esas herramientas adicionales son muy útiles. Y, argumentaría que las promesas de ES6 incluso faltan algunos de los conceptos básicos como la promisificación que son útiles en casi todos los proyectos de node.js.

Estoy más familiarizado con la biblioteca de promesa de Bluebird, así que hablaré principalmente de mi experiencia con esa biblioteca.

Entonces, aquí están mis 6 razones principales para usar una biblioteca Promise más capaz

  1. Interfaces asíncronas no prometidas : .promisify() y .promisifyAll() son increíblemente útiles para manejar todas esas interfaces asíncronas que aún requieren devoluciones de llamada simples y aún no devuelven promesas: una línea de código crea una versión promisificada de una interfaz completa.

  2. Más rápido : Bluebird es significativamente más rápido que las promesas nativas en la mayoría de los entornos.

  3. Secuencia de iteración de matriz asíncrona : Promise.mapSeries() o Promise.reduce() permiten iterar a través de una matriz, llamando a una operación asincrónica en cada elemento, pero secuenciando las operaciones asincrónicas para que sucedan una tras otra, no todas al mismo tiempo hora. Puede hacerlo porque el servidor de destino lo requiere o porque necesita pasar un resultado al siguiente.

  4. Polyfill : si desea usar promesas en versiones anteriores de clientes de navegador, necesitará un polyfill de todos modos. También podría obtener un polyfill capaz. Dado que node.js tiene promesas de ES6, no necesita un polyfill en node.js, pero puede hacerlo en un navegador. Si está codificando tanto el servidor como el cliente de node.js, puede ser muy útil tener la misma biblioteca y características prometedoras en ambos (más fácil compartir código, cambio de contexto entre entornos, usar técnicas de codificación comunes para código asíncrono, etc.) .).

  5. Otras características útiles : Bluebird tiene Promise.map() , Promise.some() , Promise.any() , Promise.filter() , Promise.each() y Promise.props() que en ocasiones son útiles. Si bien estas operaciones se pueden realizar con promesas de ES6 y código adicional, Bluebird viene con estas operaciones ya preconstruidas y probadas, por lo que es más simple y menos código usarlas.

  6. Advertencias integradas y rastros de pila completa : Bluebird tiene una serie de advertencias integradas que lo alertan sobre problemas que probablemente sean un código incorrecto o un error. Por ejemplo, si llama a una función que crea una nueva promesa dentro de un controlador .then() sin devolver esa promesa (para vincularla a la cadena de promesa actual), entonces, en la mayoría de los casos, es un error accidental y Bluebird le dará una advertencia a tal efecto. Aquí se describen otras advertencias integradas de Bluebird.

Aquí hay más detalles sobre estos diversos temas:

Promisificar todos

En cualquier proyecto node.js, inmediatamente uso Bluebird en todas partes porque uso mucho .promisifyAll() en módulos estándar node.js como el módulo fs .

Node.js en sí no proporciona una interfaz prometedora para los módulos integrados que hacen asincrónica IO como el módulo fs . Por lo tanto, si desea usar promesas con esas interfaces, puede codificar manualmente un envoltorio de promesas alrededor de cada función de módulo que use u obtener una biblioteca que pueda hacer eso por usted o no usar promesas.

Promise.promisify() y Promise.promisifyAll() proporcionan un ajuste automático de las API asíncronas de convención de llamadas de node.js para devolver promesas. Es extremadamente útil y ahorra tiempo. Lo uso todo el tiempo.

Aquí hay un ejemplo de cómo funciona:

const Promise = require(''bluebird''); const fs = Promise.promisifyAll(require(''fs'')); fs.readFileAsync(''somefile.text'').then(function(data) { // do something with data here });

La alternativa sería crear manualmente su propio envoltorio de promesa para cada API de fs que desea utilizar:

const fs = require(''fs''); function readFileAsync(file, options) { return new Promise(function(resolve, reject) { fs.readFile(file, options, function(err, data) { if (err) { reject(err); } else { resolve(data); } }); }); } readFileAsync(''somefile.text'').then(function(data) { // do something with data here });

Y, debe hacer esto manualmente para cada función de API que desee usar. Esto claramente no tiene sentido. Es el código repetitivo. También podría obtener una utilidad que haga esto por usted. Promise.promisify() y Promise.promisifyAll() son una utilidad de este tipo.

Otras características útiles

Estas son algunas de las características de Bluebird que específicamente encuentro útiles (hay un par de ejemplos de código a continuación sobre cómo pueden guardar código o acelerar el desarrollo):

Promise.promisify() Promise.promisifyAll() Promise.map() Promise.reduce() Promise.mapSeries() Promise.delay()

Además de su útil función, Promise.map() también admite una opción de concurrencia que le permite especificar cuántas operaciones se deben permitir que se ejecuten al mismo tiempo, lo cual es particularmente útil cuando tiene mucho que hacer, pero puede No abrume algunos recursos externos.

Algunos de estos pueden llamarse independientes y usarse en una promesa que se resuelve en un iterable que puede ahorrar mucho código.

Polyfill

En un proyecto de navegador, dado que en general aún desea admitir algunos navegadores que no tienen soporte de Promise, terminará necesitando un polyfill de todos modos. Si también está usando jQuery, a veces puede usar el soporte de promesa integrado en jQuery (aunque en algunos aspectos es dolorosamente no estándar, quizás arreglado en jQuery 3.0), pero si el proyecto involucra alguna actividad asíncrona significativa, encuentro Las características extendidas en Bluebird son muy útiles.

Más rápido

También vale la pena señalar que las promesas de Bluebird parecen ser significativamente más rápidas que las promesas integradas en V8. Vea esta publicación para más discusión sobre ese tema.

Falta una gran cosa Node.js

Lo que me haría considerar usar Bluebird menos en el desarrollo de node.js sería si node.js construyera una función promisificada para que pudieras hacer algo como esto:

const fs = requirep(''fs''); fs.readFileAsync(''somefile.text'').then(function(data) { // do something with data here });

O simplemente ofrezca métodos ya prometidos como parte de los módulos integrados.

Hasta entonces, hago esto con Bluebird:

const Promise = require(''bluebird''); const fs = Promise.promisifyAll(require(''fs'')); fs.readFileAsync(''somefile.text'').then(function(data) { // do something with data here });

Parece un poco extraño tener el soporte de promesa ES6 integrado en node.js y que ninguno de los módulos incorporados devuelva promesas. Esto debe resolverse en node.js. Hasta entonces, uso Bluebird para promisificar bibliotecas completas. Por lo tanto, parece que las promesas se implementan aproximadamente en un 20% en node.js ahora, ya que ninguno de los módulos integrados le permite usar promesas con ellos sin envolverlos manualmente primero.

Ejemplos

Aquí hay un ejemplo de promesas simples frente a promisify de Bluebird y Promise.map() para leer un conjunto de archivos en paralelo y notificar cuando haya terminado con todos los datos:

Promesas simples

const files = ["file1.txt", "fileA.txt", "fileB.txt"]; const fs = require(''fs''); // make promise version of fs.readFile() function fsReadFileP(file, options) { return new Promise(function(resolve, reject) { fs.readFile(file, options, function(err, data) { if (err) return reject(err); resolve(data); }); }); } Promise.all(files.map(fsReadFileP)).then(function(results) { // files data in results Array }, function(err) { // error here });

Bluebird Promise.map() y Promise.promisifyAll()

const Promise = require(''bluebird''); const fs = Promise.promisifyAll(require(''fs'')); const files = ["file1.txt", "fileA.txt", "fileB.txt"]; Promise.map(files, fs.readFileAsync).then(function(results) { // files data in results Array }, function(err) { // error here });

Este es un ejemplo de promesas simples frente a promisify y Promise.map() Bluebird cuando lee un montón de URL de un host remoto donde puede leer como máximo 4 a la vez, pero desea mantener tantas solicitudes en paralelo como sea posible:

Promesas simples de JS

const request = require(''request''); const urls = [url1, url2, url3, url4, url5, ....]; // make promisified version of request.get() function requestGetP(url) { return new Promise(function(resolve, reject) { request.get(url, function(err, data) { if (err) return reject(err); resolve(data); }); }); } function getURLs(urlArray, concurrentLimit) { var numInFlight = 0; var index = 0; var results = new Array(urlArray.length); return new Promise(function(resolve, reject) { function next() { // load more until concurrentLimit is reached or until we got to the last one while (numInFlight < concurrentLimit && index < urlArray.length) { (function(i) { requestGetP(urlArray[index++]).then(function(data) { --numInFlight; results[i] = data; next(); }, function(err) { reject(err); }); ++numInFlight; })(index); } // since we always call next() upon completion of a request, we can test here // to see if there was nothing left to do or finish if (numInFlight === 0 && index === urlArray.length) { resolve(results); } } next(); }); }

Bluebird Promises

const Promise = require(''bluebird''); const request = Promise.promisifyAll(require(''request'')); const urls = [url1, url2, url3, url4, url5, ....]; Promise.map(urls, request.getAsync, {concurrency: 4}).then(function(results) { // urls fetched in order in results Array }, function(err) { // error here });

Después de que Node.js agregó soporte nativo para las promesas, ¿todavía hay razones para usar bibliotecas como Q o BlueBird?

Por ejemplo, si está comenzando un nuevo proyecto y supongamos que en este proyecto no tiene dependencias que usen estas bibliotecas, ¿podemos decir que realmente no hay más razones para usar tales bibliotecas?