nodejs超出最大的调用栈错误问题


Posted in NodeJs onDecember 27, 2017

今天早上老大和我说之前项目里面的那个数据要改动,要对 mongodb 中每条记录进行 update 操作,你写个脚本跑一下吧。

然后,我默默的回到电脑前,努力工作的一天又开始了。由于此表数据量有点略大,该有一千多万条记录。所以考虑使用 mongodb 的 cursor 游标来进行遍历修改。

程序实现的代码大致如下

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

然后让它慢慢跑吧,可是一个令我郁闷的事情发生了。当游标跑到接近500万的时候,程序崩了,提示Uncaught RangeError: Maximum call stack size exceeded

竟然告诉我爆栈了,什么情况? 哎,排查代码,开始填坑。发现我上面递归调用了modify() ,而且递归次数有点小多(1000多万条记录的表啊),可能是函数不断的递归调用导致它的调用栈不断的增加,然后越来越大,最终就没有然后了,爆栈了。看来得给个机会让node进行垃圾回收一下,要想让它有机会垃圾回收那就只得终结一下递归啊。使用系统的setTimeout();来跳出递归调用栈吧。

代码修改如下

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

在跑一下试试。。。。ok,好使了。但是运行有点慢啊,因为我每次都让它跳出递归调用栈了。这样虽然没问题但是没必要,因为400多万才会出现爆栈呢。加个计数器吧,等调用栈有点大的时候在跳出来。

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

总结

以上所述是小编给大家介绍的nodejs超出最大的调用栈错误问题,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

NodeJs 相关文章推荐
快速掌握Node.js之Window下配置NodeJs环境
Mar 21 NodeJs
Nodejs中的this详解
Mar 26 NodeJs
nodejs利用http模块实现银行卡所属银行查询和骚扰电话验证示例
Dec 30 NodeJs
nodejs进阶(6)—连接MySQL数据库示例
Jan 07 NodeJs
图片上传之FileAPI与NodeJs
Jan 24 NodeJs
详解nodejs微信公众号开发——5.素材管理接口
Apr 11 NodeJs
nodejs入门教程四:URL相关模块用法分析
Apr 24 NodeJs
Nodejs中使用captchapng模块生成图片验证码
May 18 NodeJs
nodeJS模块简单用法示例
Apr 21 NodeJs
nodejs中函数的调用实例详解
Oct 31 NodeJs
NodeJs 模仿SIP话机注册的方法
Jun 21 NodeJs
nodejs中使用worker_threads来创建新的线程的方法
Jan 22 NodeJs
nodejs实现简单的gulp打包
Dec 21 #NodeJs
nodejs调取微信收货地址的方法
Dec 20 #NodeJs
基于nodejs实现微信支付功能
Dec 20 #NodeJs
nodeJS微信分享
Dec 20 #NodeJs
NodeJS爬虫实例之糗事百科
Dec 14 #NodeJs
nodejs实现爬取网站图片功能
Dec 14 #NodeJs
NodeJs form-data格式传输文件的方法
Dec 13 #NodeJs
You might like
360通用php防护代码(使用操作详解)
2013/06/18 PHP
thinkphp3.2中实现phpexcel导出带生成图片示例
2017/02/14 PHP
javascript动态加载三
2012/08/22 Javascript
Jquery+CSS3实现一款简洁大气带滑动效果的弹出层
2013/05/15 Javascript
各浏览器对document.getElementById等方法的实现差异解析
2013/12/05 Javascript
javascript对话框使用方法(警告框 javascript确认框 提示框)
2014/01/07 Javascript
JQuery EasyUI 数字格式化处理示例
2014/05/05 Javascript
JavaScript对象数组的排序处理方法
2015/10/21 Javascript
完善的jquery处理机制
2016/02/21 Javascript
Bootstrap+jfinal退出系统弹出确认框的实现方法
2016/05/30 Javascript
JS 获取HTML标签内的子节点的方法
2016/09/21 Javascript
Angularjs手动解析表达式($parse)
2016/10/12 Javascript
实现隔行换色效果的两种方式【实用】
2016/11/27 Javascript
js仿搜狐视频记录片列表展示效果
2020/05/30 Javascript
canvas绘图不清晰的解决方案
2017/02/28 Javascript
详解VueJs异步动态加载块
2017/03/09 Javascript
从vue基础开始创建一个简单的增删改查的实例代码(推荐)
2018/02/11 Javascript
使用Vue的slot插槽分发父组件内容实现高度复用、更加灵活的组件(推荐)
2018/05/01 Javascript
对vue事件的延迟执行实例讲解
2018/08/28 Javascript
mpvue将vue项目转换为小程序
2018/09/30 Javascript
如何使用vuex实现兄弟组件通信
2018/11/02 Javascript
js中int和string数据类型互相转化实例
2019/01/16 Javascript
使用js实现一个简单的滚动条过程解析
2019/09/10 Javascript
JS面向对象编程——ES6 中class的继承用法详解
2020/03/03 Javascript
python实现随机密码字典生成器示例
2014/04/09 Python
Python通过select实现异步IO的方法
2015/06/04 Python
python pycurl验证basic和digest认证的方法
2018/05/02 Python
python实现多人聊天室
2020/03/31 Python
用python打印菱形的实操方法和代码
2019/06/25 Python
详解CSS3中@media的实际使用
2015/08/04 HTML / CSS
Betsey Johnson官网:妖娆可爱的连衣裙及鞋子、手袋和配件
2016/12/30 全球购物
世界上最大的曲棍球商店:Pro Hockey Life
2017/10/30 全球购物
焊接专业毕业生求职信
2013/10/01 职场文书
学校工作推荐信范文
2014/07/11 职场文书
2014年幼儿园安全工作总结
2014/11/10 职场文书
CSS实现九宫格布局(自适应)的示例代码
2022/02/12 HTML / CSS