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 相关文章推荐
14款NodeJS Web框架推荐
Jul 11 NodeJs
Nodejs关于gzip/deflate压缩详解
Mar 04 NodeJs
详解nodejs微信公众号开发——2.自动回复
Apr 10 NodeJs
nodejs入门教程六:express模块用法示例
Apr 24 NodeJs
nodejs操作mysql实现增删改查的实例
May 28 NodeJs
nodejs mysql 实现分页的方法
Jun 06 NodeJs
Nodejs回调加超时限制两种实现方法
Jun 09 NodeJs
nodejs实现爬取网站图片功能
Dec 14 NodeJs
nodejs(officegen)+vue(axios)在客户端导出word文档的方法
Jul 31 NodeJs
nodejs遍历文件夹下并操作HTML/CSS/JS/PNG/JPG的方法
Nov 01 NodeJs
使用koa-log4管理nodeJs日志笔记的使用方法
Nov 30 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
Fatal error: Call to undefined function curl_init()解决方法
2010/04/09 PHP
奇怪的PHP引用效率问题分析
2012/03/23 PHP
基于curl数据采集之单页面采集函数get_html的使用
2013/04/28 PHP
Yii不依赖Model的表单生成器用法实例
2014/12/04 PHP
PHP 设计模式系列之 specification规格模式
2016/01/10 PHP
PHP基于redis计数器类定义与用法示例
2018/02/08 PHP
代码生成器 document.write()
2007/04/15 Javascript
jquery实现动态菜单的实例代码
2013/11/28 Javascript
Nodejs Stream 数据流使用手册
2016/04/17 NodeJs
JavaScript中的ajax功能的概念和示例详解
2016/10/17 Javascript
Bootstrap和Java分页实例第二篇
2016/12/23 Javascript
javaScript+turn.js实现图书翻页效果实例代码
2017/02/16 Javascript
jQuery.ajax向后台传递数组问题的解决方法
2017/05/12 jQuery
Bootstrap弹出框(Popover)被挤压的问题小结
2017/07/11 Javascript
使用jquery的jsonp如何发起跨域请求及其原理详解
2017/08/17 jQuery
html中通过JS获取JSON数据并加载的方法
2017/11/30 Javascript
[19:26]TNC vs EG (BO3)
2018/06/07 DOTA
python实现比较两段文本不同之处的方法
2015/05/30 Python
python urllib爬取百度云连接的实例代码
2017/06/19 Python
python smtplib发送带附件邮件小程序
2018/05/22 Python
简单了解Python matplotlib线的属性
2019/06/29 Python
Python中关于浮点数的冷知识
2019/09/22 Python
python numpy数组复制使用实例解析
2020/01/10 Python
捷克原创男装和女装购物网站:Bolf.cz
2018/04/28 全球购物
BannerBuzz加拿大:在线定制横幅印刷、广告和标志
2020/03/10 全球购物
大学毕业生通用自荐信范文
2013/10/31 职场文书
鞋类设计与工艺专业销售求职信
2013/11/01 职场文书
商务日语毕业生自荐信
2013/11/23 职场文书
婚礼证婚人证婚词
2014/01/08 职场文书
2014年个人委托书范本
2014/10/13 职场文书
2014年稽查工作总结
2014/12/20 职场文书
实习单位指导教师评语
2014/12/30 职场文书
2015年教学管理工作总结
2015/05/20 职场文书
暑假开始了,你的暑假学习计划写好了吗?
2019/07/04 职场文书
详解Javascript实践中的命令模式
2021/05/05 Javascript
Java8中接口的新特性使用指南
2021/11/01 Java/Android