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+express+html5 实现拖拽上传
Aug 08 NodeJs
基于NodeJS的前后端分离的思考与实践(三)轻量级的接口配置建模框架
Sep 26 NodeJs
nodejs中的fiber(纤程)库详解
Mar 24 NodeJs
基于html5和nodejs相结合实现websocket即使通讯
Nov 19 NodeJs
Nodejs爬虫进阶教程之异步并发控制
Feb 15 NodeJs
NodeJS的Promise的用法解析
May 05 NodeJs
nodejs个人博客开发第二步 入口文件
Apr 12 NodeJs
nodejs使用http模块发送get与post请求的方法示例
Jan 08 NodeJs
利用nodeJs anywhere搭建本地服务器环境的方法
May 12 NodeJs
用Electron写个带界面的nodejs爬虫的实现方法
Jan 29 NodeJs
nodejs检测因特网是否断开的解决方案
Apr 17 NodeJs
Nodejs技巧之Exceljs表格操作用法示例
Nov 06 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
3
2006/10/09 PHP
强制PHP命令行脚本单进程运行的方法
2014/04/15 PHP
phpmailer发送邮件之后,返回收件人是否阅读了邮件的方法
2014/07/19 PHP
Yii2实现增删改查后留在当前页的方法详解
2017/01/13 PHP
jQuery中add实现同时选择两个id对象
2010/10/22 Javascript
JavaScript判断访问的来源是手机还是电脑,用的哪种浏览器
2013/12/12 Javascript
javascript日期格式化示例分享
2014/03/05 Javascript
js隐式全局变量造成的bug示例代码
2014/04/22 Javascript
JQuery实现表格动态增加行并对新行添加事件
2014/07/30 Javascript
Node.js中的事件驱动编程详解
2014/08/16 Javascript
百度多文件异步上传控件webuploader基本用法解析
2016/11/07 Javascript
15个非常实用的JavaScript代码片段
2016/12/18 Javascript
Bootstrap实现提示框和弹出框效果
2017/01/11 Javascript
vue实现app页面切换动画效果实例
2017/05/23 Javascript
Vue.set()动态的新增与修改数据,触发视图更新的方法
2018/09/15 Javascript
微信小程序动画组件使用解析,类似vue,且更强大
2019/08/01 Javascript
JS实现联想、自动补齐国家或地区名称的功能
2020/07/07 Javascript
用Python编写简单的微博爬虫
2016/03/04 Python
python去掉行尾的换行符方法
2017/01/04 Python
Python 自动化表单提交实例代码
2017/06/08 Python
python opencv设置摄像头分辨率以及各个参数的方法
2018/04/02 Python
Python中创建二维数组
2018/10/17 Python
pycham查看程序执行的时间方法
2018/11/29 Python
使用python3实现操作串口详解
2019/01/01 Python
实例详解python函数的对象、函数嵌套、名称空间和作用域
2019/05/31 Python
Python抓新型冠状病毒肺炎疫情数据并绘制全国疫情分布的代码实例
2020/02/05 Python
Python 如何反方向迭代一个序列
2020/07/28 Python
Python爬虫过程解析之多线程获取小米应用商店数据
2020/11/14 Python
大学生入党自我鉴定
2013/10/31 职场文书
财务与信息服务专业推荐信
2013/11/28 职场文书
心理健康课教学反思
2014/02/13 职场文书
高校优秀辅导员事迹材料
2014/05/07 职场文书
实习公司领导推荐函
2014/05/21 职场文书
该怎么书写道歉信?
2019/07/03 职场文书
Opencv中cv2.floodFill算法的使用
2021/06/18 Python
浅析python中特殊文件和特殊函数
2022/02/24 Python