用这段代码:
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);
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);
});
主要问题是您需要这样做:
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
函数不存在。