我试图创建一个递归函数来迭代数据集,但它没有正确地突破并且是无限的
jsfiddle 显示的代码
var data = [{a: 1,b: 1}, {a: 2,b: 2}],z = 0;
function some(a, b, cbk) {
console.log(a + ':' +b);
cbk();
}
function main() {
var cbk = function () {
if (z < data.length) {
main();
} else {
console.log('end');
}
z++;
}
some(data[z].a, data[z].b, cbk);
}
main();
为什么这是一个无限循环?
答案 0 :(得分:1)
我被告知要取消删除这个,因为它是负责任的,虽然我越来越讨厌,我发现我已经注意到了我的错误并做到了这一点。
var data = [{
a: 1,
b: 1
}, {
a: 2,
b: 2
}],
z = 0;
function some(a, b, cbk) {
console.log(a + ':' +b);
cbk();
}
function main() {
var cbk = function () {
z++;
if (z < data.length) {
main();
} else {
console.log('end');
}
}
some(data[z].a, data[z].b, cbk);
}
main();
答案 1 :(得分:1)
的 jsFiddle Demo
强> 的
这里有一些事情使得递归失败涉及迭代控制。从z = 0
开始,与.length
进行比较,z
需要在条件检查if( z < .length )
之前预先增加。
原因是在递归路径之后,z从不递增,因此递归是无限的,导致页面锁定。因此,z需要在递归调用发生之前进行处理,最好在与.length进行比较之前进行处理。
在原始版本中,这不仅发生在if语句之后,而且发生在递归调用之后。修复此迭代器将修复递归。
if (++z < data.length) {
答案 2 :(得分:0)
我不知道你读代码是多么流利,但我试图将线性递归的概念分解为我想象的通用方式
function recurse(data, /* fns */ step, worker, joiner, /* vals */ first, empty) {
function recursor(data, current) {
var result = worker(data, current), // do work with current iteration
next = step(data, current); // find the next iteration
if (next !== null) // if found
return joiner( // return
result, // the result from this time
recursor(data, next) // + the result from next time
);
else // if not found
return joiner( // return
result, // just this result
empty // this join is helpful for joining arrays/objects/etc
);
}
return recursor(data, first); // start it
}
所以,一个基于你正在做的事情的例子
var data = [{a: 1,b: 1}, {a: 2,b: 2}];
function init(data) {
function logger(data, i) { // a function describing what to do
var e = data[i]; // with this iteration
console.log(e.a + ':' + e.b);
return e.a;
}
function step(data, i) { // a function describing how to find
i = i + 1; // the next iteration
if (i < data.length) return i;
return null; // null = end
}
function add(a, b) { // a function describing how to join
return a + b; // two iterations together
}
return recurse(data, step, logger, add, 0, 0);
}
init(data); // run everything safely in it's own closure
/*
1:1
2:2
3 // === 1 + 2 + 0, from return of logger and result of add
*/
当然,在实践中你可以在很多方面做到这一点,而不是为每件事做一个函数,而step
通常可以简化得那么多,你不需要var
对于result
和next
,因为您不必为if
测试缓存任何内容。