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 相关文章推荐
NodeJS中利用Promise来封装异步函数
Feb 25 NodeJs
nodejs修复ipa处理过的png图片
Feb 17 NodeJs
Nodejs Stream 数据流使用手册
Apr 17 NodeJs
Nodejs实现短信验证码功能
Feb 09 NodeJs
NodeJS创建最简单的HTTP服务器
May 15 NodeJs
Nodejs中使用phantom将html转为pdf或图片格式的方法
Sep 18 NodeJs
nodejs基于mssql模块连接sqlserver数据库的简单封装操作示例
Jan 05 NodeJs
nodejs更改项目端口号的方法
May 13 NodeJs
详解webpack打包nodejs项目(前端代码)
Sep 19 NodeJs
NodeJS模块与ES6模块系统语法及注意点详解
Jan 04 NodeJs
nodeJS进程管理器pm2的使用
Jan 09 NodeJs
详解利用nodejs对本地json文件进行增删改查
Sep 20 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
帅气的琦玉老师
2020/03/02 日漫
php 团购折扣计算公式
2011/11/24 PHP
laravel框架模型、视图与控制器简单操作示例
2019/10/10 PHP
Expandable "Detail" Table Rows
2007/08/29 Javascript
2007/12/23更新创意无限,简单实用(javascript log)
2007/12/24 Javascript
浅谈jquery回调函数callback的使用
2015/01/30 Javascript
jQuery实现统计输入文字个数的方法
2015/03/11 Javascript
jquery+css3实现会动的小圆圈效果
2016/01/27 Javascript
模拟javascript中的sort排序(简单实例)
2016/08/17 Javascript
JS实现鼠标滑过显示边框的菜单效果
2016/09/21 Javascript
NodeJS和BootStrap分页效果的实现代码
2016/11/07 NodeJs
bootstrap组件之导航组件使用方法
2017/01/19 Javascript
关于vue.js v-bind 的一些理解和思考
2017/06/06 Javascript
JavaScript之underscore_动力节点Java学院整理
2017/07/03 Javascript
微信小程序template模板实例详解
2017/10/27 Javascript
vue2单元测试环境搭建
2018/05/24 Javascript
vue 项目中使用Loading组件的示例代码
2018/08/31 Javascript
微信小程序 自定义弹窗实现过程(附代码)
2019/12/05 Javascript
vue-列表下详情的展开与折叠案例
2020/07/28 Javascript
js禁止查看源文件屏蔽Ctrl+u/s、F12、右键等兼容IE火狐chrome
2020/10/01 Javascript
[00:43]拉比克至宝魔导师密钥展示
2018/12/20 DOTA
python操作 hbase 数据的方法
2016/12/18 Python
Python分析学校四六级过关情况
2017/11/22 Python
对python .txt文件读取及数据处理方法总结
2018/04/23 Python
儿童编程python入门
2018/05/08 Python
Python高级特性与几种函数的讲解
2019/03/08 Python
Pytorch转tflite方式
2020/05/25 Python
电子商务专业学生职业生涯规划
2014/03/07 职场文书
项目合作协议书
2014/04/16 职场文书
微笑面对生活演讲稿
2014/05/13 职场文书
2015年艾滋病防治工作总结
2015/05/22 职场文书
企业催款函范本
2015/06/24 职场文书
2015暑期社会实践个人总结
2015/07/13 职场文书
Javascript中的解构赋值语法详解
2021/04/02 Javascript
新手初学Java List 接口
2021/07/07 Java/Android
Oracle查看表空间使用率以及爆满解决方案详解
2022/07/23 Oracle