Home > Web Front-end > JS Tutorial > body text

How to solve the maximum call stack exceeded error in nodejs

亚连
Release: 2018-06-15 11:27:14
Original
1844 people have browsed it

This article mainly introduces the problem of nodejs exceeding the maximum call stack error. Friends who need it can refer to it

This morning, the boss told me that the data in the previous project needs to be changed, and every file in mongodb needs to be modified. To update records, you can write a script and run it.

Then, I silently returned to the computer, and the day of hard work began again. Since the data volume of this table is a bit large, there should be more than 10 million records. So consider using mongodb's cursor to traverse and modify.

The code implemented by the program is roughly as follows

function modify(cursor) {
  cursor.hasNext(function(err,bool) {
   if(err) {
      return console.log(err); 
    } 
    if(bool) {
      cursor.next(function(err, item){
       if(err) {
       return console.log(err);
     }
     /* 此处为对数据进行update操作 */
     // 递归调用modify方法 
     return modify(cursor);
   }); 
    }else{
      console.log('finished');
    }
  })
}
var cursor = collection.find();
modify(cursor);
Copy after login

Then let it run slowly, but something happened that made me depressed. When the cursor reached close to 5 million, the program crashed, prompting Uncaught RangeError: Maximum call stack size exceeded

and actually told me that the stack was exploded. What happened? Hey, check the code and start filling in the holes. I found that I called modify() recursively above, and the number of recursions was a bit small (a table with more than 10 million records). It may be that the function's constant recursive calls caused its call stack to continue to increase, and then get bigger and bigger, and finally There is no more, the stack explodes. It seems that we need to give the node a chance to perform garbage collection. If we want it to have a chance to perform garbage collection, we have to terminate the recursion. Use the system's setTimeout(); to jump out of the recursive call stack.

The code is modified as follows

function modify(cursor) { 
  cursor.hasNext(function(err,bool) {
    if(err) {
      return console.log(err); 
    }
    if(bool) {      
      cursor.next(function(err, item){
        if(err) {
          return console.log(err);
        }
        /* 此处对数据进行update操作 */
        // 递归调用modify方法 
        return setTimeout(function(){ 
              //跳出递归调用栈
              modify(cursor);
            },0);
      }); 
    }else{
      console.log('finished');
    }
  })
}
var cursor = collection.find();
modify(cursor);
Copy after login

Try running it. . . . ok, it works. But it runs a bit slowly, because I have to make it jump out of the recursive call stack every time. Although this is okay, it is not necessary, because the stack will only explode after more than 4 million. Add a counter and pop it out when the call stack gets a little big.

var count = 0;
function modify(cursor) { 
  count++;
  cursor.hasNext(function(err,bool) {
    if(err) {
      return console.log(err); 
    }
    if(bool) {
      cursor.next(function(err, item){
        if(err) {
         return console.log(err);
        }
        /* 此处对数据进行update操作 */
        // 递归调用modify方法 
        if(count%10000 === 0) {
          return setTimeout(function(){ 
              //跳出递归调用栈
              modify(cursor);
              },0);
        }else{
          return modify(cursor);
        }    
      }); 
    }else{
      console.log('finished');
    }
  })
}
var cursor = collection.find();
modify(cursor);
Copy after login

The above is what I compiled for everyone. I hope it will be helpful to everyone in the future.

Related articles:

How to use the Generator method in JavaScript

How to change the avatar in node

404 problem occurs when refreshing the page in react-router

Details introduction to the use of Vue event modifier capture

The above is the detailed content of How to solve the maximum call stack exceeded error in nodejs. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!