Reputation: 255
I came from c++ background, so am not much clear on callback mechanisms. Getting confused with java-script to achieve recursion. Someone please help.
This is what i want to achieve.
Method 1(on success - call Method2);
Method 2(on success - call Method3);
Method 3(on success - call Method1)
Here is my code.
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);
Once i run this it throws RangeError: Maximum call stack size exceeded error. How to achieve recursion in javascript?
Edit: I am writing a webcrawler. This is what i wanted to achieve.
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.
This can be achieved in recursion only. I understood there has to be end point/exit point. Here my exit point could be once i parse all the weblinks. it should exit.
Upvotes: 0
Views: 239
Reputation: 255
It can be achieved by setImmediate or setTimeout or process.nextTick(nodejs) functions. The efficient way is setImmediate. Reasons given in these below links.
Setimmdiate API: http://nodejs.org/api/timers.html#timers_setimmediate_callback_arg
SetImmediate vs nextTick(SO) : setImmediate vs. nextTick
Explanation 1 : http://www.nczonline.net/blog/2013/07/09/the-case-for-setimmediate/
Explanation 2 : http://howtonode.org/understanding-process-next-tick
SetImmediate is not supported in some browsers as per my knowledge. It is supported only in IE10 as of now. In server-side, nodejs supports those apis.
Upvotes: 0
Reputation: 13226
Javascript doesn't support tail call optimization. Everything is just pushed onto the stack, but doesn't pop off until the end case is reached.
You're maxing out the stack size before the end condition is met.
is there any way to overcome that ?
There are various approaches, but I think the simplest would be set use setTimeout
to call your function with its parameters at a later time.
For example:
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
This will try to print out all the numbers from 0 to 100000, but it hit the max stack size before it reaches the end.
So instead of calling it directly, you can defer the time of execution by passing it into the setTimeout
function, which will take function and it's parameters and run it at a later time. An added benefit of using setTimeout
is that the calls will be asynchronous, which means other code can run in the meantime.
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!
More on how the scheduling works: http://ejohn.org/blog/how-javascript-timers-work/
Upvotes: 1
Reputation: 3263
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>);
Note: It require some condition to break the recursion loop, else it wont end the loop.
Upvotes: 0
Reputation: 648
You need to say when to stop, or else it will just keep on calling each method, resulting in your error.
Upvotes: 2