2013-07-07 12 views
15

Node.js dispone ora di generatori.Cercando di capire generatori/rendimento in node.js - cosa esegue la funzione asincrona?

La mia comprensione è che i generatori possono essere utilizzati per scrivere codice che sembra essere molto più lineare ed evita la codifica dell'inferno di callback e della piramide di doom.

Quindi, a questo punto, la mia comprensione è che all'interno di un generatore, il codice viene eseguito finché non raggiunge un'istruzione "yield". L'esecuzione della funzione del generatore si interrompe a questo punto. L'istruzione yield specifica un valore restituito che può essere una funzione. Normalmente questa sarebbe una funzione I/O di blocco, che normalmente dovrebbe essere eseguita in modo asincrono.

La funzione di ritorno del rendimento viene restituita a qualsiasi cosa chiamata generatore.

La mia domanda è, cosa succede a questo punto? Cosa esegue esattamente la funzione I/O di blocco restituita dalla resa?

È corretto che per scrivere il codice generatore/rendimento che sembra essere lineare, ci deve essere un tipo specifico di funzione che chiama il generatore, una funzione che scorre attraverso il generatore ed esegue ogni funzione asincrona restituita dal cede e restituisce il risultato della funzione asynch nel generatore?

Non mi è ancora chiaro esattamente come viene eseguita la funzione asynch restituita dal rendimento. Se viene eseguito dalla funzione che chiama il generatore, viene eseguito in modo asincrono? Sto indovinando così perché fare altrimenti comporterebbe il comportamento di bloccaggio.

In sintesi le mie domande:

  1. Per scrivere "lineare" di codice asincrono con i generatori, è necessario che vi sia una funzione di chiamata che scorre oltre il generatore, l'esecuzione delle funzioni fruttati come callback e restituendo il risultato del callback nel generatore?
  2. Se la risposta alla domanda 1 è sì, esattamente come vengono eseguite le funzioni rese - in modo asincrono?

Qualcuno può offrire una panoramica/riepilogo migliore di come funziona l'intero processo?

+0

Ciò può aiutare in qualche modo, anche i collegamenti al codice nel post: http: //bjouhier.wordpress.com/2013/06/01/bring-asyncawait-to-life-in-javascript/ –

+0

Si consiglia di dare un'occhiata a https://github.com/loveencounterflow/coffy-script che ha una introduzione graduale passo dopo passo alla programmazione asincrona con i generatori. – flow

risposta

10

Quando la scrittura di codice asincrono con generatori avete a che fare con due tipi di funzioni:

  • normali funzioni dichiarate con function. Queste funzioni non possono produrre rendimento. Non puoi scrivere codice asincrono in sincrono con loro perché corrono fino al completamento; è possibile gestire solo il completamento asincrono tramite le richiamate (a meno che non si invochi potenza aggiuntiva come la libreria node-fibers o una trasformazione di codice).
  • generatore funzioni dichiarate con function*. Queste funzioni possono produrre rendimento. Puoi scrivere il codice asincrono nello stile di sincronizzazione al loro interno perché possono produrre. Ma è necessaria una funzione complementare che crea il generatore, gestisce i callback e riprende il generatore con una chiamata next ogni volta che viene attivato un callback.

Ci sono diverse librerie che implementano le funzioni complementari . Nella maggior parte di queste librerie, la funzione companion gestisce un singolo function* alla volta e devi inserire un wrapper su ogni function* nel tuo codice. La libreria galassia (che ho scritto) è un po 'speciale perché può gestire function* chiamando altri function* senza wrapper intermedi. La funzione companion è un po 'complicata perché deve gestire una pila di generatori.

Il flusso di esecuzione può essere difficile da comprendere a causa della piccola danza yield/next tra il function* e la funzione companion. Un modo per comprendere il flusso è scrivere un esempio con la libreria di tua scelta, aggiungere le istruzioni console.log sia nel codice che nella libreria ed eseguirlo.

4

Se [la funzione di blocco io] viene eseguita dalla funzione che chiama il generatore , viene eseguita in modo asincrono? Sto indovinando così perché fare altrimenti comporterebbe il comportamento di bloccaggio.

Non penso che i generatori eseguano la gestione asincrona delle attività. Con i generatori, solo una cosa è in esecuzione allo stesso tempo - è solo che una funzione può arrestare l'esecuzione e passare il controllo a un'altra funzione. Per esempio,

function iofunc1() { 
    console.log('iofunc1'); 
} 

function iofunc2() { 
    console.log('iofunc2'); 
} 

function* do_stuff() { 
    yield iofunc1; 
    yield iofunc2; 
    console.log('goodbye'); 
} 


var gen = do_stuff(); 
(gen.next().value)(); 
(gen.next().value)(); //This line won't begin execution until the function call on the previous line returns 
gen.next(); //continue executing do_stuff 

Se avete letto alcuni articoli su nodejs generatori:

  1. http://jlongster.com/2012/10/05/javascript-yield.html
  2. http://jlongster.com/A-Study-on-Solving-Callbacks-with-JavaScript-Generators
  3. http://jlongster.com/A-Closer-Look-at-Generators-Without-Promises

...tutti impiegano funzioni/librerie aggiuntive per aggiungere l'esecuzione asincrona.

2

1: scrivere "lineare" codice asincrono con generatori, è necessario che vi sia una funzione di chiamata che scorre sul generatore, eseguire funzioni come callback ceduto e restituendo il risultato della callback posteriore nel generatore?

Sì. Chiamiamolo "launcher".

2: se la risposta alla domanda 1 è sì, esattamente come vengono eseguite le funzioni rese in modo asincrono?

All'interno del generatore, si fornisce un array con: la funzione e i relativi parametri. Nel chiamante di controllo (launcher), si usa fn.apply (.., callback) per chiamare async, ponendo la chiamata a "generator.next (data);" (riprendi) all'interno del callback.

la funzione asincrona viene eseguita in modo asincrono, ma il generatore sarà "sospeso" al punto di snervamento, fino al callback viene chiamata (e quindi "generator.next (dati)" viene eseguita)

lib lavoro completo e campioni: https://github.com/luciotato/waitfor-es6

Problemi correlati