2015-06-21 15 views
14

Sto tentando di usare coroutine di Bluebird come segue:Bluebird utilizzo coroutine

var p = require('bluebird'); 
//this should return a promise resolved to value 'v' 
var d = p.coroutine(function*(v) { yield p.resolve(v); }); 
//however this prints 'undefined' 
d(1).then(function(v){ console.log(v); }); 

Che non è corretto qui?

risposta

20

Citando il documentation of coroutine,

Restituisce una funzione che può utilizzare yield a cedere promesse. Il controllo viene restituito al generatore quando si verifica la promessa resa.

Quindi, la funzione può fare uso di yield, ma yield non viene utilizzata per restituire il valore dalla funzione. Qualunque cosa si stia restituendo da quella funzione con l'istruzione return sarà il valore effettivo risolto della funzione coroutine.

Promise.coroutine fa semplicemente yield dichiarazione di attesa per la promessa di risolvere e l'attuale yield espressione verrà valutata al valore risolto.

Nel tuo caso, l'espressione

yield p.resolve(v); 

saranno valutate al 1 e dal momento che si restituisce nulla dalla funzione in modo esplicito, per impostazione predefinita, JavaScript restituisce undefined. Ecco perché ottieni undefined come risultato.


Per risolvere questo problema, si può effettivamente restituire il valore ceduto, come questo

var p = require('bluebird'); 

var d = p.coroutine(function* (v) { 
    return yield p.resolve(v); 
}); 

d(1).then(console.log); 
+0

così, potrei anche fare un 'p.coroutine (funzione *() {yield d (1);})' giusto? – pkyeck

+0

@pkyeck Cosa significa 'd' nel tuo caso? – thefourtheye

+0

la coroutine che hai creato nell'esempio – pkyeck

1

Cominciamo con il codice :)

var d = p.coroutine(function*(v) { 
    yield p.resolve(v); 
}); 

Quando si esegue d (1) , la coroutine del bluebird fa la magia e valuta la funzione di promessa cioè p.resolve (v). Ora, come funziona coroutine chiamando la funzione promessa e quindi eseguendo il rendimento effettivo, il flusso ritorna al generatore reale dopo l'esecuzione della promessa resa.

Ora la resa non è per restituire valori diversi dalla funzione di risoluzione che potrebbe essere utilizzata per ottenere i valori nel "poi" in caso di promesse.

Quindi non viene restituito alcun valore e quindi non viene definito.

Quindi ci sono due cose che si possono fare:

Prima semplicemente restituire il valore di resa esplicitamente:

var d = p.coroutine(function* (v) { 
    return p.resolve(v); 
}) 

questo restituirà il valore ottenuto nella 'resa' ottenuto con l'esecuzione della promessa , quindi il valore può essere ottenuto usando 'then'. come

d(7).then((val) => { 
    console.log(val); 
}); 

ma cosa succede se si dispone di un altro, la funzione promessa di cedere. io.e qualcosa di simile:

var d = bluebird.coroutine(function* (val) { 
    yield bluebird.resolve(val); 
    console.log('i am here'); 
    yield(bluebird.resolve('here' + val)); 
    console.log('i am at the last'); 
}); 

poi facendo la cosa di ritorno qui non sarebbe eseguire la funzione cioè un'altra resa se si torna al primo valore di rendimento nel codice qui sopra, quindi il codice dopo la prima resa non verrà eseguito.

Quindi non è una cosa che posso fare è quello di gestire il 'poi' della data promessa ci si piace:

var d = bluebird.coroutine(function* (val) { 
    yield bluebird.resolve(val).then(function(data) { 
     // process data here 
     console.log(data); 
    }); 
}); 

d(4).then(() => { 
    console.log('done execution'); 
}); 

e questo si può fare con qualsiasi non di promesse fruttate. Ecco un codice demo:

var bluebird = require('bluebird'); 
bluebird.coroutine(function *temp() { 
    console.log('starting'); 
    yield(new Promise((resolve, reject) => { 
      setTimeout(function() { 
        return resolve('first yield data'); 
      }, 2000); 
    }).then((data)=>{console.log(data)})); 

    yield(new Promise((resolve, reject) => { 
      setTimeout(function() { 
        resolve('second yield data'); 
      }, 3000); 
    }).then((data) => {console.log(data)})); 
})().then(() => { 
     console.log('finally done'); 
    }); 

questo modo si può produrre il maggior numero di promesse nella Bluebird e ottenere i valori risolti da loro nei rispettivi 'poi' ed elaborare i dati risolti.