2011-08-11 17 views
6

Acabo de echar un vistazo al muy interesante task.js de Dave Herman. En su ejemplo que tiene esta línea:Sintaxis de rendimiento extraño en JavaScript

var [foo, bar] = yield join(read("foo.json"), 
           read("bar.json")).timeout(1000); 

Estoy familiarizado con los generadores, pero no entiendo cómo la expresión de rendimiento se evalúa como algo que se puede asignar a [foo, bar]. De hecho, no esperaba que la expresión se pueda asignar a nada, ya que básicamente es lo mismo que devolver.

La sintaxis de rendimiento de JS todavía parece un poco infravalorada y no pude encontrar información sobre esto.

Así que para aclarar mi pregunta: ¿qué termina siendo asignado a foo y bar?

+0

Por cierto que quería añadir una palabra clave "taskjs" pero parece que no tengo la reputación suficiente para esto. –

+1

Por favor, recuerde hacer una pregunta :-) – driis

Respuesta

6

En realidad, el párrafo pertinente es un poco por debajo de https://developer.mozilla.org/En/New_in_JavaScript_1.7:

Una vez que un generador se ha iniciado llamando a su método next(), que puede utilizar send(), pasando de un valor específico que será tratada como el resultado de la última yield. El generador devolverá el operando del yield siguiente.

creo que esto sólo es relevante si el generador es utilizado por llamar a sus métodos directamente, no cuando bucle sobre sus valores - un bucle siempre se llamará next() en el generador y nunca send().

En cierto modo, la ejecución del generador es similar a la multitarea cooperativa. El generador se ejecuta hasta que se encuentra la declaración yield. Devuelve el control a quien haya llamado al next() o send() en el generador. La persona que llama luego continúa ejecutándose hasta que se realiza la siguiente llamada next() o send(); ahora el generador se está ejecutando nuevamente. Cada vez que los valores se pueden pasar de ida y vuelta.

Aquí un ejemplo sencillo:

function gen() 
{ 
    var [foo, bar] = yield 1; 
    console.log("Generator got: " + foo + ", " + bar); 
} 

// This creates a generator but doesn't run it yet 
var g = gen(); 

// Starts generator execution until a yield statement returns a value 
var result = g.next() 
console.log("Received from generator: " + result); 

// Continue generator execution with [2, 3] being the return value 
// of the yield statement. This will throw StopIteration because the 
// iterator doesn't have any more yield statements. 
g.send([2, 3]); 
0

https://developer.mozilla.org/En/New_in_JavaScript_1.7

La función que contiene la palabra clave de rendimiento es un generador. Cuando lo llamas, sus parámetros formales están ligados a argumentos reales, pero su cuerpo no es realmente evaluado. En cambio, se devuelve un generador-iterador. Cada llamada al método next() del generador-iterador realiza otra pasada a través del algoritmo iterativo. El valor de cada paso es el valor especificado por la palabra clave yield. Piense en yield como la versión de retorno generador-iterador, que indica el límite entre cada iteración del algoritmo. Cada vez que llame a next(), el código del generador se reanuda a partir de la declaración que sigue al rendimiento.

+2

Entiendo todo eso por lo que no entiendo por qué la declaración de rendimiento no se produce en un bucle (que esperaría obtener la semántica del estilo de iterador) y por qué hay una directa asignación realizada usando cualquier rendimiento que se evalúe. Como dices, es como un retorno, así que me parece que decir 'var something = return something_else;'. Nunca he visto ese uso y no estoy seguro de lo que significaría. –