Post Top Ad

Your Ad Spot

martes, 15 de septiembre de 2020

Generadores ES6

 


Los generadores en ES6 son un tipo especial de función que devuelve un iteradorSin embargo, son bastante diferentes a la función estándar de ejecución del molino en JavaScript. Los generadores pueden pausarse mientras se ejecutan y devolver varios valores cuando la ejecución se detiene y se reanuda. Utiliza un iterador para llamar a un generador varias veces. Veamos algunos ejemplos para comprender mejor cómo funcionan los generadores.


Definición de una función de generador

Observe el asterisco justo delante de la generateit()función. Este *símbolo indica que se trata de una función generadora. Además de esto, podemos ver estas nuevas declaraciones dentro de la función que hacen uso de la yieldpalabra clave. La función produce un valor de 200 y también un valor de 300. Una vez que se obtienen ambos valores, la función saldrá. A continuación, ejecutamos la generateit()función y asigna un iterador en un estado de pausa a la variable iterCuando desconectamos el valor de iter.next(), vemos el resultado de Object {value: 200, done: false} . Entonces, en esencia, la función se detuvo en la primera declaración de rendimiento. El siguiente es el resultado de varias llamadas a iter.next():

Por este código y salida, vemos que un generador se completa como lo hace un iterador.


Ceder indefinidamente

En este ejemplo, crearemos una función generadora que puede producir un rendimiento indefinido. En otras palabras, nunca se puede agotar. En lugar de tener valores codificados como nuestros primeros ejemplos de un generador, aquí usaremos algo de lógica dentro de la función del generador para establecer un punto de partida y luego una operación de incremento en cada rendimiento.


Usando un generador en un for ofbucle

Dado que un generador está controlado por un iterador, puede utilizar fácilmente las funciones del generador dentro de los bucles. En este ejemplo a continuación, tenemos una construcción interesante en la que realmente llamamos generateit () justo dentro del bucle. También agregamos una condición en el interior para evitar que este bucle for no continúe para siempre.


Una mirada más cercana a Yielding

Aquí reescribiremos nuestra función de generador para que no produzca un valor específico. Si intentamos llamar a esta función generadora, obtenemos un resultado de Object {value: undefined, done: false}


Una nueva forma de yield

La siguiente función de generador se utiliza de yielduna manera nueva. Dentro de la función del generador, ahora tenemos una variable que se inicializa yieldInmediatamente después de esto, simplemente desconectaremos una cadena con el valor de resultcontenido en ella.

Con esto en su lugar, llamamos al generador y asignamos el iterador a iterLa primera llamada a iter.next()es lo que pone en marcha el generador, por así decirlo, lo que hace que el generador ceda inmediatamente. En este punto, ahora puede llamar iter.next()y pasar un valor. Este valor se establece en la variable de resultado. Entonces, cuando pasamos 777, podemos ver que El resultado es 777 es lo que se cierra la sesión en la consola.

Envuelva la segunda llamada a iter.next()en una console.log()declaración. La primera línea sigue mostrando lo mismo. El resultado es 777 del generador, sin embargo, ahora también podemos insertar el objeto iterador. Ese objeto se valueestableció en undefinedy se doneestableció en trueEsto se debe a que una vez que pasamos 777iter.next(), no hubo más rendimiento en el generador, por lo que en ese punto, está hecho.


Usando rendimiento en lugar de una expresión

Podemos usar la palabra clave yield en lugares donde es más probable que vea una expresión. Veamos cómo podría funcionar esto.

Este ejemplo configura una nueva matriz y luego inicializa su valor en 3 yieldpalabras clave. Después de eso, queremos cerrar la sesión arrayOfYieldspara ver qué contiene.

Con esto en su lugar, llamamos al generador, luego llamamos iter.next()cuatro veces. Una vez para inicializar, y luego tres veces más pasando un valor para ser colocado en la matriz en cada llamada. Inspeccionar la consola nos muestra la matriz final de [“PHP”, “JavaScript”, “Linux”] .


yield la precedencia es muy baja

Cuando utilice la palabra clave yield en una expresión, debe colocarla entre paréntesis como una buena práctica. Si no lo hace, es posible que no obtenga los resultados que espera. En el siguiente ejemplo, queremos hacer uso de la multiplicación en nuestra función generadora. Envolvemos el rendimiento entre paréntesis para que las cosas funcionen; de lo contrario, se ignora el rendimiento y la expresión falla.


Produciendo un solo valor y una matriz en el mismo generador

Aquí obtendremos el valor de 77, y luego una matriz que tiene 3 valores de cadena diferentes contenidos dentro. Una vez más, activamos el generador, luego hacemos sucesivas llamadas a iter.next().valuemientras cerramos la sesión del resultado. En la primera llamada a iter.next().valueobtenemos el valor de 77. En la segunda llamada a iter.next().value, obtenemos la matriz completa de una sola vez. La llamada final a iter.next().valueda un resultado de undefinedya que el iterador está agotado en este punto.


Cediendo cada valor de una matriz de uno en uno

Si desea cerrar la sesión de cada valor individualmente, puede hacer uso de la delegación de iteradores . Cuando colocamos el asterisco justo después de la palabra clave de rendimiento como vemos a continuación, esto significa que el rendimiento espera algo que sea iterable. En este caso, es una matriz, y definitivamente es iterable. Con esta construcción dentro de un generador, encontrará que este iterador interno reemplaza temporalmente al iterador para *generateit()Entonces, cuando usa yield*, está delegando otro iterador al generador. Una vez que ese iterador se consume por completo, el iterador anterior tomará el control nuevamente.


throwreturnen generadores

Es posible obtener un mayor grado de control sobre los iteradores haciendo uso de las palabras clave throwreturnExaminemos algunos ejemplos para ver cómo funcionan.

El siguiente fragmento tiene un generador que produce tres valores. Observe que existen en un bloque try / catch. Siguiendo la definición del generador, iniciamos el generador de forma normal y luego desconectamos algunos valores. El primer valor desconectado es el de 'Fruta'. Después de esto, sin embargo, hacemos una llamada a iter.throw () y pasamos un mensaje de 'Hey ahora'. El resultado de su llamada es que recibimos un objeto con un valor establecido en indefinido y listo en verdadero. Lo que esto significa es que se lanzó una excepción y se manejó mediante el bloque de captura. No tenemos ninguna lógica en el bloque de captura, por lo que falla silenciosamente. En la última llamada a iter.next(), el generador ya se completó, por lo que obtenemos el objeto con el valor establecido en indefinido y listo en verdadero.


throw en generadores

Si omitimos el bloque try catch del generador, el primer valor aún se imprime. Cuando presionamos iter.throw(), se lanza una excepción, pero el generador no tiene lógica de captura, por lo que finaliza el script por completo. Es por eso que no vemos ningún objeto en la última llamada a iter.next()La conclusión es que, si desea invocar iter.throw()su código, debe asegurarse de tener un bloque try catch para manejarlo.


return en generadores

Hacer uso de la función de retorno es una forma de limpiar sus generadores. A continuación, hacemos uso de nuestra función de generador familiar, la iniciamos y luego desconectamos el primer valor. Después de esto, vemos algo nuevo en console.log (iter.return ('Hola ahora')); Cuando se llama a esto, podemos ver en la salida que obtenemos un objeto con el valor establecido en 'Hey ahora' y listo en verdadero. La llamada final a iter.next () nos da el objeto iterador terminado familiar con el valor establecido en indefinido y hecho establecido en verdadero. Llamar a return en un iterador es una buena manera de terminar el iterador y completar su ejecución. Cualquiera que sea el parámetro que se pasa a iter.return ()se convierte en el valor del objeto devuelto. Desde que llamamos a regresar, nunca llegamos a 'Café' o 'Avena' en el generador. La función de retorno lo terminó.


Ejemplo de una secuencia de Fibonacci usando un generador

Aquí hay un ejemplo de la secuencia de Fibonacci común que hace uso de un generador para producir el resultado. Tenga en cuenta que este cachorro es una secuencia infinita, por lo que solo use el iterador next (), o podría bloquear su navegador.


Usando el operador de propagación con generadores

Recientemente aprendimos sobre los operadores de propagación y cómo se pueden usar para consumir un iterable. Esto significa que podemos usar el operador de propagación con generadores. Veamos un ejemplo de eso. Aquí tenemos una función generadora llamada estaciones. Produce cuatro valores diferentes como cabría esperar. Observe que cuando lanzamos nuestro generador, primero hacemos una llamada a theseasons.next () que nos da el valor de Object {value: “Spring”, done: false} . Después de esto, hacemos uso del operador de difusión con el iterable de este modo: [...theseasons]Para esto obtenemos todos los valores de rendimiento restantes de la función del generador como una matriz, ¡genial! Finalmente, llamamos a theseasons.next () nuevamente solo para confirmar que sí, nuestro generador está agotado y ha alcanzado un estado finalizado.

Nota especial: nunca querrá hacer uso del operador de propagación en un iterable generado si el generador es una secuencia infinita. La razón es que esto creará un ciclo interminable de rendimientos que consumirá toda la memoria y bloqueará el navegador.


Resumen de generadores ES6

Un generador en ES6 es un tipo especial de función que devuelve un iterador. Existen algunas diferencias entre las funciones del generador y las funciones regulares. Los enumeramos aquí.

  • Las funciones generadoras crean y devuelven iteradores
  • Hay un asterisco después de la palabra clave de función para denotar un generador.
  • Puede utilizar la palabra clave yield en la función de iterador creada. Al escribir rendimiento 'Bazinga', el iterador devuelve el objeto de {valor: 'Bazinga', hecho: falso}
  • El resultado obtenido es el siguiente valor del proceso de iteración. La ejecución de la función del generador se detiene en el punto de ceder. Una vez que un consumidor de datos solicita otro valor, la ejecución de la función del generador se reanuda ejecutando la instrucción después del último rendimiento.
  • Puede utilizar la palabra clave return para finalizar la iteración.

Las funciones de iterador son un tema complicado en ES6 y llevará algún tiempo familiarizarse con ellas. A medida que ES6 madura y lo vemos más en la naturaleza, estarán disponibles más aplicaciones prácticas de generadores para ver cómo hacer un mejor uso de ellos.


No hay comentarios.:

Publicar un comentario

Dejanos tu comentario para seguir mejorando!

outbrain

Páginas