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 redis 发布订阅机制封装实现方法及实例代码
Dec 15 NodeJs
nodejs和php实现图片访问实时处理
Jan 05 NodeJs
NodeJS遍历文件生产文件列表功能示例
Jan 22 NodeJs
NodeJS测试框架mocha入门教程
Mar 28 NodeJs
nodeJS实现简单网页爬虫功能的实例(分享)
Jun 08 NodeJs
NodeJS爬虫实例之糗事百科
Dec 14 NodeJs
nodejs acl的用户权限管理详解
Mar 14 NodeJs
NodeJS安装图文教程
Apr 19 NodeJs
nodejs实现日志读取、日志查找及日志刷新的方法分析
May 20 NodeJs
独立部署小程序基于nodejs的服务器过程详解
Jun 24 NodeJs
nodejs语言实现验证码生成功能的示例代码
Oct 13 NodeJs
通过实例了解Nodejs模块系统及require机制
Jul 16 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
php基础知识:类与对象(4) 范围解析操作符(::)
2006/12/13 PHP
Yii框架中memcache用法实例
2014/12/03 PHP
php图片上传类 附调用方法
2016/05/15 PHP
php简单中奖算法(实例)
2017/08/15 PHP
PHP实现模拟http请求的方法分析
2017/12/20 PHP
PHP依赖注入原理与用法分析
2018/08/21 PHP
cookie丢失问题(认证失效) Authentication (用户验证信息)也会丢失
2009/06/04 Javascript
20个非常棒的Jquery实用工具 国外文章
2010/01/01 Javascript
JQuery一种取同级值的方式(比如你在GridView中)
2012/03/15 Javascript
js跨域问题浅析及解决方法优缺点对比
2014/11/08 Javascript
jquery中获取元素里某一特定子元素的代码
2014/12/02 Javascript
微信WeixinJSBridge API使用实例
2015/05/25 Javascript
JavaScript实现上下浮动的窗口效果代码
2015/10/12 Javascript
JavaScript+CSS实现的可折叠二级菜单实例
2016/02/29 Javascript
Node.js中路径处理模块path详解
2016/11/14 Javascript
微信小程序 底部导航栏目开发资料
2016/12/05 Javascript
利用Vue.js框架实现火车票查询系统(附源码)
2017/02/27 Javascript
angularJs-$http实现百度搜索时的动态下拉框示例
2018/02/27 Javascript
微信小程序scroll-view实现字幕滚动
2018/07/14 Javascript
如何使用 vue + d3 画一棵树
2018/12/03 Javascript
Bootstrap table 实现树形表格联动选中联动取消功能
2019/09/30 Javascript
JavaScript 实现自己的安卓手机自动化工具脚本(推荐)
2020/05/13 Javascript
vue绑定数字类型 value为数字的实例
2020/08/31 Javascript
[55:04]海涛DOTA2死魂复燃6.82版本介绍
2014/09/28 DOTA
[01:25:38]DOTA2-DPC中国联赛 正赛 VG vs LBZS BO3 第一场 1月19日
2021/03/11 DOTA
在Django中输出matplotlib生成的图片方法
2018/05/24 Python
django开发post接口简单案例,获取参数值的方法
2018/12/11 Python
Python jieba库用法及实例解析
2019/11/04 Python
python2和python3哪个使用率高
2020/06/23 Python
澳大利亚网上玩具商店:Mr Toys Toyworld
2018/03/25 全球购物
美国轻奢时尚购物网站:REVOLVE(支持中文)
2020/07/18 全球购物
大学活动策划书范文
2014/01/10 职场文书
实用的简历自我评价
2014/03/06 职场文书
如何计划开一家便利店?
2019/07/31 职场文书
nginx实现动静分离的方法示例
2021/11/07 Servers
微软Win11有哪些隐藏功能? windows11多个功能汇总
2021/11/21 数码科技