如何从JavaScript中的递归生成器函数返回? [英] How do I return from a recursive generator function in JavaScript?
问题描述
我正在玩一个递归生成器函数,该函数异步返回值.我正在使用协程包装函数来调用它.代码和下面的JSBin:
I'm playing around with a recursive generator function that returns values asynchronously. I'm using a coroutine wrapper function to call it. Code and JSBin below:
http://jsbin.com/nuyovay/edit?js,console
let log = console.log.bind(console);
let err = console.error.bind(console);
function coroutine(generatorFn){
return function co() {
let generator = generatorFn.apply(this, arguments);
function handle(result) {
console.log(result);
if (result.done) {
return Promise.resolve(result.value);
}
return Promise.resolve(result.value)
.then(
res => handle(generator.next(res)),
err => handle(generator.throw(err))
);
}
try {
return handle(generator.next());
} catch (err) {
return Promise.reject(err);
}
};
}
function sleep(dur) {
return new Promise(res => {
setTimeout(() => { res() }, dur);
});
}
function* recurse(limit = 5, count = 0) {
if(count < limit) {
yield sleep(100).then(() => Promise.resolve(++count));
yield* recurse(limit, count);
}
else {
return count;
}
}
let test = coroutine(recurse);
test().then(log).catch(err);
运行此命令将返回:
Object {value: Promise, done: false}
Object {value: Promise, done: false}
Object {value: Promise, done: false}
Object {value: Promise, done: false}
Object {value: Promise, done: false}
// `value` should be 5
Object {value: undefined, done: true}
生成器的最终return
为何是undefined
?当我将上述内容与bluebird的Promise.coroutine
结合使用时,我得到的结果是相同的.我是否缺少有关递归生成器的基本知识?如何将其发送到{ value: 5, done: true }
?
How come the final return
from the generator is undefined
? When I adapt the above for use with bluebird's Promise.coroutine
, I get the same result. Am I missing something fundamental about recursive generators? How do I get it to { value: 5, done: true }
?
推荐答案
问题是您要返回count
,但是您要在父生成器中返回它.与委托生成器中的yield
不同,return
不会通过委托链自动生成.
The issue is that you are returning count
, but you're returning it in the parent generator. Unlike yield
in delegated generators, return
is not yielded back up through the delegation chain automatically.
如果要获取委托生成器的return
值,则必须直接在父生成器中分配它:
If you want to get the return
value of a delegated generator, you have to assign it directly in the parent generator:
let returnValue = yield* recurse(limit, count);
由于您使用的是递归"生成器(多个委派级别),因此您需要重复该过程并在每个委派级别返回值:
Since you're using "recursive" generators (multiple levels of delegation), you would need to repeat the process and return the value at every level of delegation:
function* recurse(limit = 5, count = 0) {
if(count < limit) {
yield sleep(100).then(() => Promise.resolve(++count));
let result = yield* recurse(limit, count); // save the return value
return result; // return it to the parent
}
else {
return count;
}
}
这篇关于如何从JavaScript中的递归生成器函数返回?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!