0

I created a foreach loop which calls Facebook's API to fetch data. But since the number of calls are too high, it gives an error that JavaScript's maximum call stack size has exceeded and it stops there. I was thinking of delaying the execution of each iteration after 5 mins or a fix interval of time. I took help from this question. Now I want to know, does executing each iteration after an interval of time clear the JavaScript call stack or not?

Code:

var updateFeeds = function(){
        db.collection("accounts").find({"status": "live"}).toArray(function(err, clients) {
        var interval = 10 * 1000;
        var i = 0;
        clients.forEach(function(client, index, array){
            setTimeout( function (i) {
                i++;
               ****code*****

            }, interval * i, i);
        });

For each client there are almost 5000 request calls inside the code. I want to clear the JavaScript heap memory after completion of each iteration.

Error: FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory

Aborted (core dumped)

Community
  • 1
  • 1
Aman Gupta
  • 1,764
  • 4
  • 30
  • 58
  • 2
    _what could be the best solution to avoid this._ better post some code to see where you got stuck. Yes there are better solutions, but you have to put your code context to answer. – Jai Jul 07 '16 at 09:31
  • @Jai Sorry for misleading the question. i simply wanted to ask whether deplaying the execution of a loop clears the call stack ? – Aman Gupta Jul 07 '16 at 09:40
  • @DEVELOPER Well, show us your code... I assume the API calls are async, so there's no need to delay the calls – XCS Jul 07 '16 at 09:41
  • @Cristy I hope this clears out what i want to achieve. – Aman Gupta Jul 07 '16 at 10:03

2 Answers2

0

You can use set timeout with an increasing timeout. You can store each timeout in an object:

var calls = {};
var urls = {
    'first': 'http://...',
    'second': 'http://...',
}
var timeout = 0;

for (var i in urls) {
    calls[i] = setTimeout(function(){
        // Make call here with urls[i];
    }, timeout);
    timeout + 5000;  // Adds 5 seconds
} 

Then if you need to cancel any of the timeouts, you can use clearTimeout(calls['first'])

The Facebook API is pretty extensive, maybe you can use a different call to get the data from all the calls in one response.

Sinan Guclu
  • 1,075
  • 6
  • 16
  • So using a larger timeout clears the javascript heap? – Aman Gupta Jul 07 '16 at 10:04
  • I'm not entirely sure what you mean by clearing the JavaScript heap. JavaScript garbage collects automatically. You can try increasing the amount of memory NodeJs has to play with by launching it with `node --max_old_space_size=8192`. See this other stack overflow [question](http://stackoverflow.com/questions/26094420/fatal-error-call-and-retry-last-allocation-failed-process-out-of-memory). – Sinan Guclu Jul 07 '16 at 10:09
  • I think Increasing the old space size will not resolve this issue. In future if no of clients increases i cannot always increase this size. I want to clear the space. – Aman Gupta Jul 07 '16 at 10:12
  • Does it happen right away? In my answer, if you were make the timeout delete it's reference from the calls object after it has received it's callback, then the garbage collector will remove it from memory. – Sinan Guclu Jul 07 '16 at 10:18
0

UPDATE: OK, instead using the loop, try to use setInterval and global variables enter code here

 globalArrayIndex = 0 
 myInterval = setInertval(function(){
      globalArrayIndex++
     /*code*/

     if(noMoremembers)
        clearInterval(myInterval)
 }, 5000)