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?
Respuestas:
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 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
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.Más rápido : Bluebird es significativamente más rápido que las promesas nativas en la mayoría de los entornos.
Secuencia de iteración de matriz asíncrona ,
Promise.mapSeries()
o lePromise.reduce()
permite 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. Puede hacerlo porque el servidor de destino lo requiere o porque necesita pasar un resultado al siguiente.Polyfill : si desea usar promesas en versiones anteriores de clientes de navegador, necesitará un polyfill de todos modos. También puede 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.) .).
Otras funciones de utilidad - Bluebird tiene
Promise.map()
,Promise.some()
,Promise.any()
,Promise.filter()
,Promise.each()
yPromise.props()
todos los cuales son en ocasiones muy útil. 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.Advertencias integradas y rastros completos de la pila : Bluebird tiene una serie de advertencias integradas que lo alertan sobre problemas que probablemente sean código incorrecto o un error. Por ejemplo, si llama a una función que crea una nueva promesa dentro de un
.then()
controlador 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 al respecto 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
.promisifyAll()
mucho en módulos node.js estándar como elfs
módulo.Node.js no proporciona una interfaz prometedora para los módulos integrados que hacen asincrónica IO como
fs
módulo. 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.Bluebird
Promise.promisify()
yPromise.promisifyAll()
proporciona 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:
La alternativa sería crear manualmente su propio envoltorio de promesa para cada
fs
API que desea utilizar: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. Bluebird
Promise.promisify()
yPromise.promisifyAll()
son una gran utilidad.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 ahorrar código o acelerar el desarrollo):
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 que es particularmente útil cuando tiene mucho que hacer, pero no puede abrumar a algunos fuera recurso.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 generalmente desea seguir siendo compatible con algunos navegadores que no tienen soporte Promise, terminará necesitando un polyfill de todos modos. Si también está utilizando jQuery, a veces puede usar el soporte de promesa integrado en jQuery (aunque en algunos aspectos es dolorosamente no estándar, tal vez 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 incorporara una función promisiva para que pudieras hacer algo como esto:
O simplemente ofrezca métodos ya prometidos como parte de los módulos integrados.
Hasta entonces, hago esto con Bluebird:
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 las promesas de Bluebird y
Promise.map()
para leer un conjunto de archivos en paralelo y notificar cuando haya terminado con todos los datos:Promesas simples
Bluebird
Promise.map()
yPromise.promisifyAll()
Aquí hay un ejemplo de promesas simples frente a las promesas de Bluebird y
Promise.map()
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 permitido:Promesas simples de JS
Bluebird Promises
fuente
return new Promise(function(resolve, rejct)
. Debería ser:reject
util.promisify
ahora, aunque no hay unpromisifyAll
equivalente directo .fs
, pero aún hay otras razones para usar Bluebird (mi favorito en particular es laconcurrency
opciónPromise.map()
) para evitar abrumar a un servicio objetivo al que debes hacer un montón de solicitudes paralelas. Además, todavía hay muchas otras interfaces no prometidas para usar Bluebird's promisifyAll. Pero, lentamente, las razones para obtener Bluebird de inmediato en cada nuevo proyecto se desvanecen a medida que node.js refuerza su soporte de promesa incorporado.