Advertencia
¡No instale este paquete como dependencia! (Ver: Comenzando)
Actualmente, las promesas son la forma de facto de manejar tareas asíncronas en JavaScript, y por eso, son una parte fundamental del conocimiento del desarrollador de JavaScript.
Sin embargo, cuando estamos aprendiendo promesas por primera vez, solo aprendemos lo suficiente para sobrevivir , es decir, aprendemos un poco de cómo usar promesas (hoy en día, muy probablemente con async/await solo), la Promise.all . Todo el método y eso es todo.
Si bien este enfoque tiene sentido para los principiantes porque es suficiente para resolver la mayoría de los problemas en su vida diaria, un problema recurrente es que se detienen allí , es decir, nunca superan este conocimiento inicial.
Y es precisamente esta postura de "aprender lo suficiente para obtener por" que mantiene a muchos desarrolladores en su nivel actual, ya que resolver problemas más complejos requiere una comprensión más profunda.
Por lo tanto, si desea llevar sus habilidades de desarrollador al siguiente nivel , nadar en aguas poco profundas no lo cortará , debe profundizar , debe comprender completamente las promesas, y cómo funcionan, debe ser competente tanto en async/await then/catch los estilos de manejo de promesas y poder orquestar tareas asíncronas de la manera más eficiente posible.
Además, como las promesas son, en última instancia, una abstracción para manejar tareas asincrónicas, es imprescindible poder abordar los problemas comunes relacionados con la programación asincrónica.
Con eso en mente, creamos este proyecto precisamente para ayudarlo a hacer esta profundidad en promesas y programación asincrónica.
Al proporcionar explicaciones y ejercicios prácticos que rodean estos temas, este proyecto tiene como objetivo ser su compañero en este viaje para dominarlos.
Incluso si ya es un desarrollador experimentado, puede aprender una o dos cosas, como, por ejemplo, es posible que desee resolver concrete/parallelMaxConcurrency , concrete/concurrencyOverride , concrete/extractingResolvers y /foundation/promise a medida que presentan algunos desafíos interesantes.
Importante
Este proyecto no está destinado a las personas que están aprendiendo promesas por primera vez, ya que supone que tiene al menos algunos conocimientos básicos de promesas, lo que representan y cómo usarlas ambas con async/await y then/catch .
Advertencia
Atención: este repositorio no está destinado a ser clonado a menos que esté contribuyendo si es un usuario final, siga las instrucciones a continuación
Primero, para instalar el proyecto, ejecute:
npm create promises-training@latestNota
Este proyecto está impulsado por el ejercicio, por lo que el objetivo principal es resolverlos.
Ocasionalmente, habrá explicaciones junto con los ejercicios para ayudarlo a comprender lo que hay que hacer, y también algún contexto sobre el problema que se está resolviendo.
Los ejercicios se dividen en tres categorías:
Importante
No hay un orden específico para las categorías, puede comenzar desde cualquiera de ellas y cambiar a otro incluso antes de terminar el otro por completo. Sin embargo, los ejercicios tienen diferentes niveles que se discutirán a continuación.
Los ejercicios se encuentran dentro de las carpetas src/exercises/<category> , donde <category> es una de las categorías mencionadas anteriormente.
Para los ejercicios de gráficos , las explicaciones base se encuentran en este readme, en la sección de gráficos y para cada ejercicio, hay un graph.png que representa el gráfico de dependencia para ese ejercicio específico.
Para los ejercicios de concreto y fundamental , las explicaciones se encuentran en el README.md dentro de la carpeta del ejercicio (por ejemplo src/exercises/concrete/parallelChunks/README.md .
Para resolver un ejercicio, debe editar el archivo src/exercises/<category>/<exercise>/exercise.ts .
Después de resolver un ejercicio, puede verificar su solución ejecutando:
npm run check < category > / < exercise > Las pruebas se encuentran dentro de src/tests .
En general, solo trabajará dentro de la carpeta de ejercicios, ya que las pruebas se diseñan de una manera que le dicen exactamente lo que salió mal sin tener que mirar su implementación, pero si por alguna razón se queda atascado o curioso, puede echarles un vistazo.
La carpeta src/lib está destinada solo al uso interno, así que no se moleste con ella.
Además, para mantener su instalación reenviada compatible con versiones futuras, no modifique ningún archivo fuera de la carpeta src/exercises .
Además de las categorías, los ejercicios también se dividen en niveles, donde los ejercicios aumentan en la dificultad a medida que avanza a través de los niveles.
Hay tres niveles:
Tenga en cuenta que esta clasificación es algo subjetiva, por lo que YMMV y tampoco necesariamente necesita completar todos los ejercicios en un nivel para pasar al siguiente.
Nota
Como puede ver, actualmente, no hay tantos ejercicios avanzados, pero la idea es que se agregarán nuevos ejercicios con el tiempo.
Cada ejercicio se acompaña de pruebas automatizadas para que pueda verificar su solución.
Para ejecutar las pruebas de un solo ejercicio, ejecute:
npm run check < category > / < exercise > Por ejemplo, para ejecutar las pruebas para el ejercicio parallelChunks , ejecute:
npm run check concrete/parallelChunksO, para ejecutar el ejercicio gráfico número 2, ejecute:
npm run check graph/2/test.test.tsNota
En el ejemplo anterior, necesitábamos agregar /test.test.ts al archivo del ejercicio, de lo contrario, también se ejecutaría para otros ejercicios de gráficos que comienzan con 2 , por ejemplo: ejercicios de 2 a 29.
Usamos Vitest como corredor de prueba, por lo que todas sus opciones de CLI están disponibles.
Además, es importante mencionar que los ejercicios de gráficos tienen algunas peculiaridades, en el sentido de que se generan automáticamente a partir del gráfico en sí , y por eso, algunos ejercicios tienen una gran cantidad de pruebas (algunos ejercicios tienen más de 100k pruebas).
Por supuesto, no los ejecutamos todos, ya que sería prohibitivamente lento, por lo que solo ejecutamos un subconjunto de ellos y es posible ajustar el número de pruebas que se ejecutan y también el subconjunto .
Puede leer más en la sección de ejercicios de gráficos.
Actualmente, hay tres categorías de ejercicio:
Una gran parte de lidiar con tareas asincrónicas es orquestarlas para que cada tarea comience lo antes posible, y para orquestar correctamente estas tareas necesitamos comprender las relaciones de dependencia entre ellas.
En esta categoría, se le presentará un gráfico de dependencia en cada ejercicio y luego orquestará las tareas en el gráfico de la manera más eficiente posible.
Como el ejercicio se centra en la orquestación en sí, las tareas se crean llamando createPromise(label) , donde label es una cadena que identifica la tarea.
Tome este gráfico, por ejemplo:

Hay dos tareas en este gráfico, A y B , y B depende de A , que está representado por la flecha que sale de B y señala A
Esto significa que B solo puede comenzar después de que A ha terminado y A , ya que no depende de ninguna otra tarea, puede comenzar de inmediato.
Por lo tanto, la implementación más eficiente para este gráfico sería:
await createPromise ( "A" ) ;
await createPromise ( "B" ) ;Las tareas también pueden depender de más de una tarea:

En este gráfico, C depende de A y B , por lo que solo puede comenzar después de que A y B hayan terminado.
Sin embargo, tanto A como B no dependen de ninguna otra tarea, por lo que pueden comenzar de inmediato.
La implementación más eficiente para este gráfico sería:
await Promise . all ( [ createPromise ( "A" ) , createPromise ( "B" ) ] ) ;
await createPromise ( "C" ) ;Las tareas también pueden tener múltiples conjuntos diferentes de dependencias donde, si se cumple alguno de los conjuntos, entonces la tarea puede comenzar:

En este gráfico, C depende de A o de B , que se representa mediante el uso de diferentes colores para cada conjunto de dependencias. Los colores en sí no tienen ningún significado específico, se usan así solo para que las dependencias se distinguen entre sí.
Por lo tanto, C puede comenzar tan pronto como A o B haya terminado.
await Promise . any ( [ createPromise ( "A" ) , createPromise ( "B" ) ] ) ;
await createPromise ( "C" ) ;Por último, pero no menos importante, las promesas tienen dos resultados posibles: se pueden cumplir o rechazar.

En este gráfico, tenemos la Tarea B que depende del cumplimiento y la Tarea C que depende del rechazo A A '.
Importante
Los bordes discontinuos se utilizan para representar rechazos de promesa.
Esto significa que B solo puede comenzar después de que A se ha cumplido y C solo puede comenzar después de que A ha sido rechazado.
Como solo uno de estos resultados es posible, se llevará a cabo B o C
Implementación correspondiente:
try {
await createPromise ( "A" ) ;
try {
await createPromise ( "B" ) ;
} catch { }
} catch {
await createPromise ( "C" ) ;
} Al hacer ejercicios de gráficos, notará que se están exportando tres funciones: mixed , asyncAwait , thenCatch .
La idea es que proporcione 3 implementaciones diferentes:
mixed : este es completamente gratis, puede mezclar tanto async/espera y luego/atrapar,asyncAwait : en este solo debes usar async/esperathenCatch : En este solo debes usar entonces/Catch.De esta manera, será competente en ambos estilos de manejo de promesas.
Además, al final del archivo, notará que las exportaciones se están envolviendo en un skipExercise , que omite las pruebas para esa implementación específica para que no ensucie la salida.
A medida que implementa una solución para cada uno de esos tres, elimine la llamada skipExercise para la implementación que desea que se ejecuten las pruebas. Por ejemplo: si ya implementó la solución mixed , elimine el skipExercise de él, pero mantenga los de asyncAwait y thenCatch hasta que las implemente.
Para ayudarlo a depurar su implementación para los ejercicios de gráficos, creamos una interfaz de usuario que le permite simular diferentes "rutas" de ejecución.
Para abrir la interfaz de usuario, ejecute:
npm run graph:uiLa interfaz de usuario se sirve como una aplicación web y se ve así.

Ahora exploremos cada sección:

La barra lateral de la izquierda le permite seleccionar el ejercicio que desea depurar.

Esta sección superior le permite seleccionar la implementación que desea depurar.

La barra lateral derecha le permite controlar el flujo de ejecución del ejercicio resolviendo/rechazando promesas.
A medida que se crean promesas, se agregan nuevas entradas a la barra lateral.

Esta sección en el centro muestra los registros de las promesas que se crearon y se resolvieron/rechazaron en cada paso.

Esta sección en la parte inferior muestra un resumen de las promesas que se resolvieron/rechazaron en cada paso, en orden.
Como los ejercicios de gráficos se basan en gráficos (DUH), es posible generar todas las pruebas posibles para un ejercicio dado automáticamente, que es lo que hacemos.
Como se podría imaginar, el número de pruebas generadas a veces es enorme, por lo que tenemos un límite en el número máximo de pruebas que se ejecutan.
Además, para prevenir los sesgos, no realizamos pruebas en el orden en que fueron generados, en cambio, las barajamos .
Este barato ocurre justo después de que se generan las pruebas por primera vez, de modo que las pruebas sean deterministas , es decir, cada vez que ejecuta pruebas de ejercicios de gráficos, ejecutará el mismo subconjunto de pruebas.
Sin embargo, es posible ajustar tanto el límite como el subconjunto de pruebas que se ejecutan.
Para ajustar la tapa, puede ejecutar npm run graph:setGraphTestsCap <number> .
Por ejemplo, para establecer el límite en 10000, ejecute:
npm run graph:setGraphTestsCap 10000 Para ajustar el subconjunto de las pruebas que se ejecutan, puede ejecutar npm run graph:shuffleGraphTestData <graph-exercise-number> , que reenviará las pruebas para el ejercicio de gráfico especificado, que luego dará como resultado un subconjunto diferente de pruebas.
Por ejemplo, para reasignar las pruebas para el ejercicio gráfico número 2, ejecute:
npm run graph:shuffleGraphTestData 2Los ejercicios de gráficos son excelentes para comprender las relaciones de dependencia entre las tareas, sin embargo, no cubren el espectro completo de posibles escenarios, ya que solo las tareas cuyas dependencias se conocen en el tiempo de compilación y fijado pueden ser representadas por un gráfico.
Por lo tanto, tenemos esta categoría de ejercicios concretos, donde se le presentarán escenarios concretos que tendrá que implementar.
Como cada ejercicio en esta categoría es único, su descripción está colocada con su carpeta.
Los ejercicios básicos están diseñados para ayudarlo a reforzar su comprensión de los fundamentos de las promesas, reimplementando las funciones relacionadas con la promesa y, eventualmente, la promesa misma.
Las descripciones se colocan con ejercicios.
Las soluciones a los ejercicios se pueden encontrar en este repositorio, por ejemplo, https://github.com/henriqueinonhe/promises-training/blob/master/src/exercises/concrete/concurrencyabort/exercise.ts.
Sin embargo, le recomendamos que solo verifique las soluciones después de que haya resuelto el ejercicio usted mismo, ya que el objetivo es que aprenda resolviendo los ejercicios.
Además, tenga en cuenta que actualmente las soluciones presentadas no son necesariamente las mejores , lo que significa que incluso si sus soluciones no se parecen a las que encontrará aquí, no significa que sean malas.
Para facilitar la actualización a versiones más nuevas, creamos un script de migración que migra automáticamente su instalación a la última versión al tiempo que preserva sus soluciones.
Para ejecutar el script de migración, ejecute:
npm create promises-training@latest -- --migrateEste proyecto tiene licencia bajo CC-by-NC-ND 4.0.
El objetivo detrás de este proyecto es ser un recurso de aprendizaje gratuito y para que permanezca gratuito y accesible para siempre.
Aquí hay una sesión de preguntas y respuestas de algunas preguntas comunes con respecto a la licencia:
¿Puedo usar este proyecto para el estudio de sí mismo o grupal?
Sí, por favor hazlo.
¿Puedo usar este proyecto en una capacitación interna de la empresa?
Sí, siempre y cuando acredite el proyecto y deje en claro que el proyecto se puede acceder libremente independientemente de la capacitación.
¿Puedo usar este proyecto para mis sesiones de mentoría/taller pagas?
Sí, siempre que acredite el proyecto, deje en claro que el proyecto se puede acceder libremente independientemente de la tutoría/taller, deje en claro que está cobrando por su tiempo y no por el proyecto en sí, deje en claro que el proyecto no es parte de su propio material y deje en claro que no lo respalde a usted ni por sus servicios.
¿Puedo usar este proyecto para mi curso en línea pagado?
Sí, siempre que acredite el proyecto, deje en claro que el proyecto se puede acceder libremente independientemente del curso en línea, deje en claro que está cobrando por su tiempo y no por el proyecto en sí, deje en claro que el proyecto no es parte de su propio material y deje en claro que no lo respalde a usted ni a sus servicios.
¿Puedo crear una bifurcación de este proyecto y usarlo para mis propios fines?
No, no puedes. Solo puede usar este proyecto como es, sin modificaciones. Esto es necesario para evitar que las personas creen horquillas y luego los cobren.
¿Puedo crear un curso en línea basado en este proyecto?
No, no puedes, porque no queremos que las personas creen "envoltorios" en torno a este proyecto y luego los cobren por ellos.
Si tiene alguna pregunta sobre la licencia, o desea hablar sobre un caso de uso específico, no dude en comunicarse conmigo en [email protected].