admin管理员组

文章数量:1315329

Why does the following recursive code cause a stack overflow if the array list is too large? How can I fix this and still retain the recursive pattern?

var list = readHugeList();

var nextListItem = function() {
    var item = list.pop();

    if (item) {
        // process the list item...
        nextListItem();
    }
};

Why does the following recursive code cause a stack overflow if the array list is too large? How can I fix this and still retain the recursive pattern?

var list = readHugeList();

var nextListItem = function() {
    var item = list.pop();

    if (item) {
        // process the list item...
        nextListItem();
    }
};
Share Improve this question edited Jul 6, 2015 at 16:00 rphv 5,5373 gold badges31 silver badges47 bronze badges asked Jul 6, 2015 at 15:41 Bibek SharmaBibek Sharma 3,3307 gold badges43 silver badges65 bronze badges 27
  • 8 JavaScript has a very limited call stack size. I believe this should change when implementations are updated for ES6 since proper tail calls is part of the spec IIRC. To fix it, you'll need to do it in asynchronous batches, but this will make your code require a callback. – user1106925 Commented Jul 6, 2015 at 15:42
  • 1 @squint Also, the maximum call stack on some browsers is a little over 1400. That is the case of Opera 12.17 and bellow. A solution would be to use a setTimeout of 1 milisecond. – Ismael Miguel Commented Jul 6, 2015 at 15:49
  • 1 You can find some browsers stack sizes here : stackoverflow./questions/7826992/… – merours Commented Jul 6, 2015 at 16:10
  • 1 @IsmaelMiguel I need recursive solution and as you mentioned earlier use of the setTimeout works so I accepted the answer. – Bibek Sharma Commented Jul 6, 2015 at 16:40
  • 1 Okey. Please consider this time. I'll keep in mind those things. I'm new to stackoverflow so I'm learning its processes – Bibek Sharma Commented Jul 6, 2015 at 16:44
 |  Show 22 more ments

3 Answers 3

Reset to default 5

This will sound weird, but use a setTimeout.

Like this:

//fill it with 50000 elements
var list = Array(50001).join('1.1').split('.');

var nextListItem = function() {
    var item = list.pop();

    if (item) { //should be list.length

        // recursion here!
        setTimeout( nextListItem, 0 );

    }
};
nextListItem();

The recursion now is endless!

Notice that some browsers don't like that 0 there.
As a side-effect, your code won't block the browser.

Seems like you are simply looping through an array. Have you tried using a simple for loop?

var list = readHugeList();
for (var i = 0; i < list.length; i++) {
    //Do something with list[i]
}
var taskList = breakBigTaskIntoMicroTasks(monsterTaskList);

// requestAnimationFrame will get executed in each 16ms of duration.
requestAnimationFrame(processTaskList);

function processTaskList(taskStartTime) {
    var taskFinishTime;

    do {
        // Assume the next task is pushed onto a stack.
        var nextTask = taskList.pop();

        // Process nextTask.
        processTask(nextTask);

        // Go again if there’s enough time to do the next task.
        taskFinishTime = window.performance.now();
       } while (taskFinishTime - taskStartTime < 3);
        if (taskList.length > 0)
            requestAnimationFrame(processTaskList);

}

本文标签: javascriptStack overflow while processing large array in recursive functionStack Overflow