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及配置app.js文件的详细步骤
May 11 NodeJs
使用forever管理nodejs应用教程
Jun 03 NodeJs
Nodejs学习笔记之NET模块
Jan 13 NodeJs
nodejs简单实现中英文翻译
May 04 NodeJs
nodejs爬虫抓取数据乱码问题总结
Jul 03 NodeJs
nodejs模块学习之connect解析
Jul 05 NodeJs
nodejs中安装ghost出错的原因及解决方法
Oct 23 NodeJs
nodejs 生成和导出 word的实例代码
Jul 31 NodeJs
nodejs中express入门和基础知识点学习
Sep 13 NodeJs
nodejs实现的http、https 请求封装操作示例
Feb 06 NodeJs
Sublime Text3 配置 NodeJs 环境的方法
May 20 NodeJs
Nodejs 数组的队列以及forEach的应用详解
Feb 25 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函数重载的替代方法--伪重载详解
2015/05/08 PHP
PHP基于单例模式编写PDO类的方法
2016/09/13 PHP
JavaScript延迟加载
2021/03/09 Javascript
实现超用户体验 table排序javascript实现代码
2009/06/22 Javascript
Jquery插件easyUi表单验证提交(示例代码)
2013/12/30 Javascript
删除节点的jquery代码
2014/01/13 Javascript
用jquery.sortElements实现table排序
2014/05/04 Javascript
jquery实现导航固定顶部的效果仿蘑菇街
2014/10/22 Javascript
JS实现FLASH幻灯片图片切换效果的方法
2015/03/04 Javascript
全面解析Bootstrap弹窗的实现方法
2015/12/01 Javascript
在React框架中实现一些AngularJS中ng指令的例子
2016/03/06 Javascript
Ext JS框架中日期函数的用法及日期选择控件的实现
2016/05/21 Javascript
Bootstrap3制作搜索框样式的方法
2016/07/11 Javascript
Bootstrap滚动监听组件scrollspy.js使用方法详解
2017/07/20 Javascript
使用vs code开发Nodejs程序的使用方法
2017/09/21 NodeJs
vue获取时间戳转换为日期格式代码实例
2019/04/17 Javascript
在Vue中使用Echarts可视化库的完整步骤记录
2020/11/18 Vue.js
详解Python的Django框架中的templates设置
2015/05/11 Python
Python中内置数据类型list,tuple,dict,set的区别和用法
2015/12/14 Python
使用Python的Django框架结合jQuery实现AJAX购物车页面
2016/04/11 Python
不管你的Python报什么错,用这个模块就能正常运行
2018/09/14 Python
详解python3安装pillow后报错没有pillow模块以及没有PIL模块问题解决
2019/04/17 Python
Django高并发负载均衡实现原理详解
2020/04/04 Python
Python虚拟环境venv用法详解
2020/05/25 Python
Laravel的加密解密与哈希实例讲解
2021/03/24 PHP
幼师专业毕业生自荐信
2013/09/29 职场文书
车间机修工岗位职责
2014/02/28 职场文书
食品安全工作方案
2014/05/07 职场文书
机械设计专业大学生职业生涯规划书范文
2014/09/13 职场文书
搞笑的爱情检讨书
2014/10/01 职场文书
2015年惩防体系建设工作总结
2015/05/22 职场文书
年终奖金发放管理制度,中小企业适用,拿去救急吧!
2019/07/12 职场文书
CSS3 Tab动画实例之背景切换动态效果
2021/08/23 HTML / CSS
Python图片验证码降噪和8邻域降噪
2021/08/30 Python
面试分析分布式架构Redis热点key大Value解决方案
2022/03/13 Redis
如何通过一篇文章了解Python中的生成器
2022/04/02 Python