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);
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);
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);
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!