我来自c ++背景,因此对回调机制不太清楚。 与java脚本混淆以实现递归。有人请帮忙。
这就是我想要实现的目标。
Method 1(on success - call Method2);
Method 2(on success - call Method3);
Method 3(on success - call Method1)
这是我的代码。
function Method1(val1, val2, callback) {
console.log('Method1' + val1);
callback(val1, Method3);
}
function Method2(val1, fn) {
console.log('Method2 ' + val1);
val1++;
fn(val1);
}
function Method3(val){
console.log('Method3 ' + val);
val++;
if(val > 1000) process.exit(0);
else {
Method1(val,2, Method2);
}
}
Method1(1,2,Method2);
一旦我运行它会抛出 RangeError:超出最大调用堆栈大小错误。 如何在javascript中实现递归?
编辑: 我正在写一个webcrawler。 这就是我想要实现的目标。
1. Get the URL to be crawled.
2. Store the content(webpage) in a file.
3. Parse the content. Get all the links in the file.
4. call step 2 for each link in the content.
这只能通过递归来实现。我明白必须有终点/退出点。 在这里,我的退出点可能是我解析所有的网络链接。它应该退出。
答案 0 :(得分:2)
你需要说什么时候停止,否则它会继续调用每个方法,导致你的错误。
答案 1 :(得分:1)
Javascript不支持尾调用优化。所有东西都被推到堆栈上,但是在到达最终案例之前不会弹出。
在达到最终条件之前,您最大化了堆栈大小。
有什么方法可以克服这个问题吗?
有各种方法,但我认为最简单的方法是设置使用setTimeout
以便稍后使用其参数调用函数。
例如:
function count(n, end) {
console.log(n);
if (n < end) {
count(n+1, end);
}
}
count(0, 100000) // More than enough to exceed the stack limit
这将尝试打印0到100000之间的所有数字,但它在到达结尾之前达到最大堆栈大小。
因此,不是直接调用它,而是可以通过将其传递到setTimeout
函数来推迟执行时间,该函数将获取函数及其参数并在以后运行它。使用setTimeout
的另一个好处是调用将是异步的,这意味着其他代码可以同时运行。
function count(n, end) {
console.log(from);
if (n < end) {
setTimeout(count, 0, n+1, end);
}
}
count(0, 100000) // More than enough to exceed the stack limit, but it will run!
有关计划如何运作的更多信息:http://ejohn.org/blog/how-javascript-timers-work/
答案 2 :(得分:0)
function Method1(<params>){
// condition
if(<params>){
Method2(<params>);
}else{
return;
}
}
function Method2(<params>){
// condition
if(<params>){
Method3(<params>);
}else{
return;
}
}
function Method3(<params>){
// condition
if(<params>){
Method1(<params>);
}else{
return;
}
}
Method1(<params>);
注意:它需要一些条件来打破递归循环,否则它不会结束循环。
答案 3 :(得分:0)
可以通过setImmediate或setTimeout或process.nextTick(nodejs)函数来实现。有效的方法是setImmediate。以下链接中给出的原因。
Setimmdiate API:http://nodejs.org/api/timers.html#timers_setimmediate_callback_arg
SetImmediate与nextTick(SO):setImmediate vs. nextTick
解释1:http://www.nczonline.net/blog/2013/07/09/the-case-for-setimmediate/
解释2:http://howtonode.org/understanding-process-next-tick
根据我的知识,某些浏览器不支持SetImmediate。它仅在IE10中受支持。在服务器端,nodejs支持那些api。