La red de desarrolladores de Mozilla tiene el siguiente ejemplo de pasar un valor a next() y cómo se captura mediante yield :
function* fibonacci() { let current = 0; let next = 1; while (true) { let reset = yield current; [current, next] = [next, next + current]; if (reset) { current = 0; next = 1; } } } const sequence = fibonacci(); console.log(sequence.next().value); // 0 console.log(sequence.next().value); // 1 console.log(sequence.next().value); // 1 console.log(sequence.next().value); // 2 console.log(sequence.next().value); // 3 console.log(sequence.next().value); // 5 console.log(sequence.next().value); // 8 console.log(sequence.next(true).value); // 0 console.log(sequence.next().value); // 1 console.log(sequence.next().value); // 1 console.log(sequence.next().value); // 2 Lo que me confunde es let reset = yield current; línea. Entiendo que current recibirá el valor pasado a next() . Lo que no entiendo es por qué el condicional if (reset) { /* ... */ } no se evaluará como verdadero una vez que current sea un valor mayor que 1.
Parece que let reset = yield current; line solo se evalúa si se pasa un valor a next() , pero no estoy seguro de que ese sea realmente el caso, y mucho menos por qué sería el caso si es así. Los documentos de MDN pasan por alto lo que realmente está sucediendo aquí.
Más explicaciones serían muy apreciadas.
EDITAR: Dicho de otra manera, ¿qué let reset = yield current; significa cuando un valor NO se pasa a next() ? Porque current sigue aumentando en valor con cada ejecución del bucle. ¿La asignación simplemente no está sucediendo?
function* fibonacci() { let current = 0; let next = 1; while (true) { let reset = yield current; console.log('reset value', reset); [current, next] = [next, next + current]; if (reset) { current = 0; next = 1; } } } const sequence = fibonacci(); console.log(sequence.next().value); // 0 console.log(sequence.next().value); // 1 console.log(sequence.next().value); // 1 console.log(sequence.next().value); // 2 console.log(sequence.next().value); // 3 console.log(sequence.next().value); // 5 console.log(sequence.next().value); // 8 console.log(sequence.next(true).value); // 0 console.log(sequence.next().value); // 1 console.log(sequence.next().value); // 1 console.log(sequence.next().value); // 2 Usando nada más que el registro de la consola. Podemos ver que la variable de reinicio obtiene el valor de indefinido cuando no se pasa nada a next() y, de lo contrario, obtiene el valor pasado a next.
Se le permite en javascript, asignar el valor undefined a una variable, eso es todo lo que está sucediendo aquí.
No me gusta cuando usan ejemplos tan irrelevantes para el código. Sin un contexto de la vida real, es difícil entender esto o por qué lo usarías.
Agregar una respuesta para proporcionar más detalles/claridad para cualquier otra persona que pueda estar tan perpleja como yo. El otro aspecto clave de este comportamiento aparentemente extraño es recordar que yield detiene la ejecución del generador hasta que se vuelve a llamar a next() . El siguiente código (una versión ligeramente modificada del código de ejemplo de MDN que se encuentra aquí: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield ) ilustra esto (preste especial atención a cuando el step variable tiene un valor):
function* counter(value) { let step; while (true) { step = yield ++value; console.log(`step = ${step}, value = ${value}`); if (step) { value += step; } } } const generatorFunc = counter(0); console.log(generatorFunc.next().value); console.log(generatorFunc.next().value); console.log(generatorFunc.next().value); console.log(generatorFunc.next(10).value); console.log(generatorFunc.next().value); console.log(generatorFunc.next(10).value);La salida:
1 "step = undefined, value = 1" 2 "step = undefined, value = 2" 3 "step = 10, value = 3" 14 "step = undefined, value = 14" 15 "step = 10, value = 15" 26