2015-06-21 8 views
14

I Bluebird Koroutinen zu verwenden bin versucht, wie folgt:Drossel Koroutine Nutzung

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); }); 

Was hier falsch ist?

Antwort

20

Zitiert die documentation of coroutine,

Gibt eine Funktion, die yield Versprechen ergeben können. Die Steuerung wird an den Generator zurückgegeben, wenn sich das abgegebene Versprechen beruhigt.

So kann die Funktion Verwendung von yield, macht aber yield wird nicht verwendet, Wert aus der Funktion zurück. Was auch immer Sie von dieser Funktion mit return Anweisung zurückgeben, wird der tatsächliche aufgelöste Wert der Coroutine-Funktion sein.

Promise.coroutine einfach macht yield Aussage Warten auf das Versprechen zu lösen und der tatsächliche yield Ausdruck wird auf den aufgelösten Wert bewertet werden.

In Ihrem Fall der Ausdruck

yield p.resolve(v); 

wird 1 ausgewertet werden und da Sie nichts von der Funktion explizit zurückkehren, standardmäßig liefert JavaScript undefined. Deshalb erhalten Sie undefined als Ergebnis.


Um dies zu beheben, können Sie tatsächlich die erbrachte Wert zurück, wie dieser

var p = require('bluebird'); 

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

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

Also, ich könnte auch eine 'p.coroutine (Funktion *() {Ausbeute d (1);})' richtig? – pkyeck

+0

@pkyeck Was ist 'd' in Ihrem Fall? – thefourtheye

+0

die Coroutine, die Sie in Ihrem Beispiel erstellt haben – pkyeck

1

uns mit Ihrem Code Lassen Sie beginnen :)

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

Wenn Sie das tun d (1) , die Coroutine des Bluebirds ist magisch und bewertet die Verheißungsfunktion, dh p.resolve (v). Nun, wie Coroutine funktioniert, ist, indem die Verheißungsfunktion aufgerufen wird und dann die tatsächliche Ausbeute ausgeführt wird, d. H. Der Ablauf kehrt nach der Ausführung der erbrachten Zusage zu dem tatsächlichen Generator zurück.

Jetzt Ausbeute sind nicht für die Rückgabe von Werten im Gegensatz zu der Auflösungsfunktion, die verwendet werden könnte, um die Werte im "dann" im Falle von Versprechen zu bekommen.

Es wird also kein Wert zurückgegeben und Sie werden nicht definiert.

So gibt es zwei Dinge, die Sie tun können:

Zuerst einfach den Ertragswert zurückgeben ausdrücklich:

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

dies wird den Wert in der ‚Ertrag‘ erhalten Rückkehr von der Ausführung der Versprechen erhalten , so kann der Wert mit 'dann' erhalten werden. wie

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

aber was, wenn Sie ein anderes haben, versprechen Funktion zu erhalten. ich.e etwas wie folgt aus:

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'); 
}); 

dann hier die Rückkehr Sache tun würde, die eine andere Ertragsfunktion heißt nicht ausführen, wenn Sie bei der ersten Ertragswert in dem obigen Code zurück, dann den Code nach der ersten Ausbeute wird nicht ausgeführt.

So gibt es eine Sache, die ich tun kann, ist das ‚dann‘ der gegebenen Versprechen gibt sich gerne zu handhaben:

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'); 
}); 

und dies kann man mit jedem nicht von ergab Versprechungen machen. Hier ist ein Demo-Code:

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'); 
    }); 

Auf diese Weise können Sie so viele Versprechungen in der drossel ergeben können und die Werte, indem sie in ihren jeweiligen ‚und dann‘ gelöst bekommen und die aufgelösten Daten verarbeiten.