没找到完整的答案...
当 Promise 被暂停时会发生什么?
这种结构是否正确?
var p = new Promise()
p.resolve(value)
function * (){
yield p
}
等同于
function * (){
yield value
}
更新
如何混合不同风格的异步编程,例如对于像koa这样的框架?
Koa中间件使用生成器进行工作,但是有很多优秀的基于promise的包(例如sequelize)。
没找到完整的答案...
当 Promise 被暂停时会发生什么?
这种结构是否正确?
var p = new Promise()
p.resolve(value)
function * (){
yield p
}
等同于
function * (){
yield value
}
更新
如何混合不同风格的异步编程,例如对于像koa这样的框架?
Koa中间件使用生成器进行工作,但是有很多优秀的基于promise的包(例如sequelize)。
当 Promise 被 yield 时会发生什么?
没有什么特别的。一个 Promise 只是一个对象。生成器将会 yield 这个 Promise,你可以订阅它:
var promise = generator().next().value;
promise.then(...);
正如 Felix 所说,promise 只是另一个可以被 yield 的值。
然而,有一种编写异步代码的风格,它以特定的方式利用了被 yield 的 promise。这包括一个周围的代码片段,它调用生成器,然后等待被 yield 的 promise 解决,只有在此之后再向生成器请求下一个值。这使得您可以将程序编写为:
function goGenerator *() {
var userData = yield getUserData();
yield checkuserData(userData);
}
当 getUserData
和 checkUserData
都返回一个 Promise 时,代码会更加简洁,不需要再写如下代码:
function goPromises() {
return getUserData() . then(checkUserData);
}
特别是涉及到更多承诺的情况下。基于生成器的风格是按顺序读取的,并且让人想起异步函数的方法。
async function goAsyncFunction() {
var userData = await getUserData();
return await checkUserData(userData);
}
但是异步函数的支持还不是很广泛。 基于生成器的方法是一种纯ES6可用的替代方案。
正如我所提到的,基于生成器的方法需要一个“包围”它的代码,知道如何处理yielded promises - 正如我所说的那样,等待它们解决后再次调用生成器。 这个的经典实现是co
- 你可以搜索一下。 或者您也可以编写自己的:
function spawn(generator) {
var iterator = generator();
return new Promise(
resolve =>
function iterate(val) {
var {value, done} = iterator.next(val);
if (done) { resolve(val); }
else { Promise.resolve(value).then(iterate); }
}()
);
}
spawn(goGenerator)
。 spawn
本身返回一个承诺,所以你可以在它上面挂其他的东西:spawn(goGenerator) . then(doMoreStuff)
。co
还有许多其他功能--例如,您可以yield
一个承诺数组,它将等待所有承诺解析,类似于Promise.all
。