Intercambio de Koa/Co/Bluebird o Q/Generators/Promises/Thunks?(Node.js)
(1)
Estoy investigando la creación de una aplicación web, en parte, con Koa, pero no entiendo cómo, por qué y por qué elegir entre la gama de tecnologías / enfoques que facilitan el trabajo "facilitando la asincronización". listado a continuación).
En general, la dispar orientación en la web sobre este tema aún deja las cosas borrosas, especialmente con respecto a la evolución de las mejores prácticas, o al menos mejores, y bajo qué escenarios. Parece que hay poco o nada en la web que lo pone todo en contexto.
Espero que las respuestas a esta gran publicación de gran culo puedan corregir eso . Además, tal vez las preguntas a continuación pueden inspirar a alguien a escribir una publicación de blog completa o similar para abordar este asunto. Mi sensación es que ni siquiera estoy cerca del único que se beneficiaría de eso.
Por lo tanto, me complacería que la comunidad brillante pudiera ayudar a responder y brindar claridad a las siguientes preguntas con respecto a las tecnologías enumeradas a continuación (en negrita):
- a) ¿Cómo y en qué circunstancias (según corresponda) complementan, complementan, sustituyen y / o se superponen soluciones entre sí?
- b) ¿Cuáles son sus compensaciones con respecto a la velocidad de rendimiento, la facilidad de manejo de errores y la facilidad de depuración?
- c) ¿Cuándo, dónde y por qué puede ser mejor usar tecnología "combinada", "tecnológica" y "aproximada"?
- d) ¿Qué tecnologías o enfoques, si los hay, pueden ser "estrellas atenuadas"?
(Esperando que las opiniones que son parte de las respuestas puedan ser bien explicadas).
===========================
Tecnologías:
* Koa *
Mi entendimiento:
Koa es una base mínima para las aplicaciones Build Node diseñadas para aprovechar las funciones de ECMAScript-6, una característica en particular son los generadores.
* Co *
Mi entendimiento:
- Co es una biblioteca de utilidades para ejecutar generadores ECMAScript-6 (que son nativos de la armonía del Nodo .011), con el objetivo de obtener algo / mucho (?) De la necesidad de escribir código repetitivo para ejecutar y administrar generadores.
- Co es intrínsecamente parte de Koa (?).
Preguntás especificas:
- Si y cómo se usa Co de manera diferente en Koa que en un contexto que no sea Koa. En otras palabras, ¿Koa es totalmente fachada Co?
- ¿Se podría reemplazar Co en Koa con alguna otra biblioteca de generadores similares si hay / hay una mejor? ¿Hay alguno?
* Bibliotecas de Promesa como "Q" y Bluebird *
Mi entendimiento:
- En cierto sentido son "polyfills" para implementar la especificación Promises / A +, si y hasta que el nodo ejecute esa especificación de forma nativa.
- Disponen de otras utilidades de conveniencia que no son de especificación para facilitar las promesas de uso, como la promisible herramienta de Bluebird.
Preguntás especificas:
- Entiendo que la especificación ECMAScript-6 hace / reflejará en gran medida la especificación Promises / A +, pero aún así, la armonía de Node 0.11v no implementa promesas de forma nativa. (¿Es esto correcto?) Sin embargo, cuando lo haga, ¿van a salir tecnologías como Q y Bluebird?
- He leído algo en el sentido de que los generadores de soporte "Q" y Bluebird. ¿Qué significa esto? ¿Significa en parte que, por ejemplo, proporcionaron hasta cierto punto la misma utilidad que Co, y en ese caso hasta qué punto?
* Fracasos y promesas *
Creo que tengo un buen manejo de lo que son, pero espero que alguien pueda proporcionar una definición sucinta y clara de "ascensor" sobre lo que es cada uno, y por supuesto, como se preguntó arriba, para explicar cuándo usar uno frente a otro - en un contexto de Koa y no en él.
Preguntás especificas:
- Pro y contras de usar algo como la promisoria Bluebird, contra decir usando Thunkify (github com / visionmedia / node-thunkify)?
===========================
Para dar un contexto adicional a esta publicación y sus preguntas , podría ser interesante que las técnicas de Koa presentadas en las siguientes páginas web puedan ser discutidas y contrastadas (especialmente en base a pros y contras):
- a) www.marcusoft. net / 2014/03 / koaintro.html (¿Dónde está el thunks o las promesas, o no estoy viendo algo?)
- b) strongloop. com / strongblog / node-js-express-introduction-koa-js-zone (Una vez más, ¿dónde están los thunks o las promesas?)
- c) github. com / koajs / koa / blob / master / docs / guide.md (¿A qué se asemeja el argumento "siguiente", y qué lo establece y dónde?)
- d) blog.peterdecroos. com / blog / 2014/01/22 / javascript-generators-first-impressions (No en un contexto Koa, pero presenta el uso de Co con una biblioteca de promesas (Bluebird), por lo que asumo que la técnica / patrón presentado aquí presta sí mismo al uso en Koa (?). Si es así, ¿qué tan bien?
¡Gracias a todos!
He estado trabajando casi de manera extensiva con generadores durante un mes, así que tal vez pueda dar un vistazo a esto. Trataré de mantener las opiniones al mínimo. Espero que ayude a aclarar algo de la confusión.
Parte de la razón de la falta de mejores prácticas y mejores explicaciones es que la función todavía es muy nueva en javascript. Todavía hay muy pocos lugares en los que pueda usar los generadores node.js y firefox siendo el más prominente, aunque Firefox se desvía un poco del estándar.
Me gustaría señalar que hay herramientas como traceur y regenerador que te permitirán usarlas para el desarrollo y te permitirán convertirlas en ES5 semi-equivalente, por lo que si encuentras que trabajar con ellas es agradable, no hay razón para no empezar a usarlas a menos que estás apuntando a navegadores arcaicos.
Generadores
Al principio, no se pensó en los generadores como una forma de manejar los flujos de control asíncronos, pero funcionan maravillosamente. Los generadores son esencialmente funciones de iterador que permiten pausar y reanudar su ejecución mediante el uso de yield.
La palabra clave de rendimiento básicamente dice que devuelva este valor para esta iteración y retomaré donde lo dejé cuando vuelva a llamar a next ().
Las funciones de generador son funciones especiales en el sentido de que no se ejecutan la primera vez que se llaman, sino que devuelven un objeto iterador con algunos métodos y la capacidad de ser utilizado en bucles for-of y de comprensión de conjuntos.
send () ,: Esto envía un valor al generador tratándolo como el último valor de rendimiento y continúa la siguiente iteración
next () ,: Esto continúa la próxima iteración del generador
throw (): Esto arroja una excepción EN el generador que hace que el generador arroje la excepción como si proviniera de la última declaración de rendimiento.
close (): Esto obliga al generador a devolver la ejecución y llama a cualquier código finalmente del generador que permite el manejo final de errores si es necesario.
Su capacidad para detenerse y reanudarse es lo que los hace tan poderosos en la gestión del control de flujo.
Co
Co se desarrolló en torno a la capacidad de los generadores para facilitar el control del flujo de manejo. No es compatible con todas las cosas que puede hacer con los generadores, pero puede utilizar la mayoría de ellos a través de su uso con menos repetición y dolor de cabeza. Y para fines de control de flujo, no he encontrado que necesite algo fuera de lo que co proporciona. Aunque para ser justos no he intentado enviar un valor a un generador durante el control de flujo, pero eso trae algunas posibilidades interesantes ...
Hay otras bibliotecas de generadores por ahí, algunas de las que puedo pensar en la parte superior de mi cabeza son suspender y gen-run. Los probé todos y co ofrece la mayor flexibilidad. La suspensión puede ser un poco más fácil de seguir si aún no está acostumbrado a los generadores, pero no puedo decir eso con autoridad.
En lo que respecta a los nodos y las mejores prácticas, diría que actualmente Co gana sin problemas con la cantidad de herramientas de soporte que se han creado para hacerlo. Con suspender al mejor finalista.
Co funciona tanto con promesas como con thunks y se utilizan para la declaración de rendimiento para que co sepa cuándo continuar la ejecución del generador en lugar de que usted tenga que llamar a next () manualmente. Co también admite el uso de generadores, funciones de generador, objetos y matrices para un mayor soporte de control de flujo.
Al ceder una matriz o un objeto, puede realizar operaciones paralelas en todos los elementos cedidos. Al ceder a una función de generador o generador, co delegará más llamadas al nuevo generador hasta que se complete y luego reanudará la llamada al generador actual, lo que le permite crear mecanismos de control de flujo muy interesantes con un código mínimo repetitivo.
Promesas
Si bien dije que mantendría las opiniones al mínimo, me gustaría declarar que para mí las promesas son probablemente el concepto más difícil de entender. Son una herramienta poderosa para mantener el código, pero son difíciles de comprender el funcionamiento interno y pueden llegar con algunos inconvenientes si se usan para un control de flujo avanzado.
La manera más fácil que se me ocurre para explicar las promesas es que son un objeto devuelto por una función que mantiene el estado de la función y una lista de devoluciones de llamadas para llamar cuando se ha ingresado o se ha ingresado un estado específico del objeto.
Las bibliotecas de promesa en sí mismas no irán a ningún lado pronto. Agregan un montón de cosas buenas para las promesas incluidas hechas () que no entraron en la especificación ES6. Sin mencionar el hecho de que las mismas bibliotecas se pueden usar en el navegador y en el nodo las tendremos durante mucho tiempo.
Thunks
Los thunk son solo funciones que toman una devolución de llamada de parámetro único y devuelven otra función que están envolviendo.
Esto crea un cierre que permite al código de llamada crear una instancia de la función que pasa en su devolución de llamada para que se pueda contar cuando se completa el método.
En mi opinión, los zumbidos son bastante sencillos de entender y usar, pero no son la herramienta adecuada para todo. Por ejemplo, spawn es un gran problema para crear un thunk, puedes hacerlo pero no es fácil.
Thunks vs. Promises
Estos no son mutuamente exclusivos y se pueden usar fácilmente juntos, pero por lo general es mejor para su cordura elegir uno y apegarse a él. O al menos elegir una convención para que pueda saber fácilmente cuál es cuál. Los zumbidos corren más rápido desde mi experiencia, pero no lo he comparado. La mayoría de esto es probablemente porque es una abstracción más pequeña y no tiene mecanismos de manejo de errores integrados.
Por lo general, creará algo que requiera manejo de errores, por lo que las ganancias en el rendimiento general de los thunk podrían igualar fácilmente o favorecer las promesas dependiendo de su código.
Cuándo usar
Generadores: cuando puede decir con seguridad que su aplicación podrá ejecutarse a la vanguardia, ya sea Firefox solo para el navegador o nodo> 0.11.3
Los he usado mucho en la empresa en la que me encuentro ahora y no podría estar más contento con los mecanismos de flujo de control y la evaluación perezosa que permiten.
Promesas frente a zumbidos: esto depende de ti y de lo cómodo que estés trabajando con cada uno. No proporcionan los mismos beneficios ni resuelven el mismo problema. Las promesas ayudan a lidiar directamente con el problema de asincronización, los thunk solo aseguran que una función tome el parámetro de devolución de llamada necesario para que pase otro código.
Puede usarlos juntos y siempre que pueda mantenerlos de modo que sea obvio cuál es el que no tendrá problemas.
Promesas / Giros con generadores: sugiero que lo haga cada vez que use generadores para controlar el flujo. No es necesario, pero es más fácil simplemente como usar co como una abstracción para controlar el flujo con generadores es más fácil. Menos código para escribir, más fácil mantenimiento y menos posibilidades de que te encuentres con una caja de borde con la que alguien más no se haya topado todavía.
Koa
No voy a entrar en muchos detalles sobre koa. Baste decir que es similar a express pero escrito para aprovechar los generadores. Esto le otorga algunas ventajas únicas, como un manejo de errores más fácil y middleware en cascada. Había formas de llevar a cabo todas estas tareas antes, pero no eran elegantes y, a veces no eran las más efectivas.
Nota especial: los generadores abren una puerta de posibilidades que realmente aún no hemos explorado. Al igual que se pueden usar para el flujo de control cuando ese no era su diseño inicial, estoy seguro de que se pueden usar para resolver muchos otros problemas con los que normalmente tenemos problemas en javascript. Probablemente sean las mentes más brillantes que yo las que averigüen de qué otra manera podemos usarlas, pero al menos empezaré a jugar con ellas y comprenderé mejor de lo que son capaces. Todavía hay más regalos para los generadores que vienen en ES.next.