2015-06-21 21 views
14

我試圖使用藍鳥的協同程序如下:青鳥協同程序使用

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

什麼是不正確嗎?

回答

20

引述documentation of coroutine

返回可以使用yield得到承諾的功能。當承諾的承諾解決時,控制權返回給發電機。

所以,功能可以使用yield,但yield不用於從函數返回值。無論您使用return聲明,該函數返回的結果都將是協程函數的實際解析值。

Promise.coroutine只是使yield語句等待解決的承諾和實際yield表達式將被評估爲已解決的值。

在你的情況,

yield p.resolve(v); 

將進行評估,以1既然你什麼都不是從函數返回明確,默認情況下,JavaScript的返回undefined表達。這就是爲什麼你得到undefined的原因。


爲了解決這個問題,實際上你可以返回產生價值,這樣

​​
+0

所以,我也可以做'p.coroutine(function *(){yield d(1);})'right? – pkyeck

+0

@pkyeck在你的情況下,「d」是什麼? – thefourtheye

+0

您在示例中創建的協程 – pkyeck

1

讓我們先從你的代碼:)

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

當你這樣做d(1) ,藍鳥的協同程序是神奇的,並且評估了promise函數,即p.resolve(v)。現在,協程的工作是通過調用promise函數,然後執行實際產量,即在執行產生的承諾後,流量返回到實際的發生器。

現在yield不是用於返回值,不同於解析函數,它可用於在promise中使用'then'來獲取值。

所以沒有值返回,因此你得到未定義。

因此,有兩件事情可以做:

首先簡單地返回明確屈服值:

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

這將返回由承諾的執行獲得的「收益率」得到的值,因此可以使用'then'來獲得值。 像

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

但如果有另一個承諾函數產生。一世。Ë是這樣的:

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

然後做回事情在這裏,如果你在第一次屈服值在上面的代碼中的第一個收益率將不執行後返回,那麼代碼將不會執行其他產量函數,即。

所以有一件事我可以做的是處理給定的諾言「然後」有自身喜歡:

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

,這可以用任何沒有得到承諾的事情。 這裏是一個演示代碼:

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

這樣你就可以得到在藍鳥儘可能多的承諾,並獲得各自的「然後」由他們解決的價值觀和處理解決數據。