2015-12-05 12 views
14

Questo codice genera un errore:JavaScript resa dalla funzione nidificata all'interno generatore

function *giveNumbers() { 
    [1, 2, 3].forEach(function(item) { 
     yield item; 
    }) 
} 

Questo è probabilmente perché resa è all'interno di una funzione che non è un generatore. C'è un modo elegante per superare questo? Voglio dire altro che:

function *giveNumbers() { 
    let list = [1, 2, 3]; 
    for (let i = 0; i < list.length; i++) { 
     yield list[i]; 
    } 
} 

risposta

10

This is probably because yield is inside a function that is not a generator.

Sì. Non è possibile utilizzare yield dai callback.

Is there an elegant way to overcome this?

Dipende dal caso d'uso. Di solito non vi è alcun motivo per voler effettivamente fare il yield da un callback.

Nel tuo caso, si vuole un ciclo for…of, che è superiore a .forEach in almost every aspect comunque:

function *giveNumbers() { 
    for (let item of [1, 2, 3]) 
     yield item; 
} 
+2

Ceterum censeo 'forEach' delendam esse a ES6. – Bergi

+2

Per quelli di voi che non conoscono il latino (come me) o sono troppo pigri per google-translate: "' forEach' sarà sicuramente cancellato in ES6 ". – Palisand

+0

@Palisand * [Inoltre, considero] (https://en.wikipedia.org/wiki/Carthago_delenda_est) che 'forEach' deve (dovrebbe) essere cancellato a partire da ES6 * – Bergi

2

resa restituisce il risultato al chiamante.
supponiamo che il callback forEach sia un generatore (non è un problema impostare un generatore di costumi lì) - significa che quando il callback yield restituisce il risultato - lo restituisce a forEach.

In sostanza, nella sua domanda che cosa attemp fare è:

callback -> yields to forEach -> yields to giveNumbers -> yields to caller 

Quindi, forEach dovrebbe dare il risultato di nuovo a giveNumbers. ma dal momento che lo forEach non funziona in questo modo, è impossibile senza ricotivare gli array con il costume forEach.

In realtà, il secondo frammento è il il più elegante per iniziare.

0

È inoltre possibile utilizzare while e passare gli argomenti come tale (Demo)

function *giveNumbers(array, start) { 
    var index = start || 0; 
    while(array.length > index + 1) { 
     yield array[index++]; 
    } 
    return array[index]; 
} 


var g = giveNumbers([1,2,3], 0); 

var finished = false; 

while(!finished) { 
    var next = g.next(); 
    console.log(next.value); 
    if(next.done) { 
     finished = true; 
    } 
} 
+1

Perché il downvote ?? – tsuz

Problemi correlati