使用这段代码:
function * foo(ctx) {
// process some things
// yield some async stuff...
return 'foo';
}
Q.async(function * (ctx) {
return yield foo(ctx);
})(this).done(function(result) {
console.log(result);
});
我希望result
是foo()
的结果(即'foo'
),但它实际上是 实际的生成器对象!
我在这里缺少什么或不理解?
虽然答案是很好的解决方案,但我认为我甚至可以通过简单地做
来缩短整个事情result = Q.async(foo)(this);
答案 0 :(得分:3)
async
是一个生成器函数装饰器。您打算用作承诺蹦床的任何功能都必须进行装饰。此外,我已选择将this
上下文传递为this
。
var foo = Q.async(function *() {
// yield, yield, yield
return "foo";
});
var bar = Q.async(function *() {
// yield, yield, yield
return foo.call(this);
});
bar.call(this).done(function (result) {
console.log(result);
});
答案 1 :(得分:1)
主要问题是你需要这样做:
return yield* foo(ctx);
您之前所说的是return yield foo(ctx)
。那将foo(ctx)
创建一个生成器,然后yield ...
将生成生成器。由于生成器不是承诺,Q将认为它已解决并在生成器中生成yield
结果。然后返回yield
的结果,因此async
函数会生成一个生成器对象。通过添加*
,您可以告诉生成器接管而不是屈服,因此yield* foo(ctx)
的结果实际上是foo
而不是返回foo
的生成器。
我在本地遇到的第二个问题(如果你在foo中有实际的异步代码,你可能没有)是如果foo
生成器是同步的而不是异步的,它似乎立即返回foo
而不是返回解析为foo
的承诺,因此.done
函数不存在。