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 模块开发及发布详解分享
Mar 07 NodeJs
NodeJS使用jQuery选择器操作DOM
Feb 13 NodeJs
详解Nodejs基于mongoose模块的增删改查的操作
Dec 21 NodeJs
nodejs利用http模块实现银行卡所属银行查询和骚扰电话验证示例
Dec 30 NodeJs
nodejs进阶(6)—连接MySQL数据库示例
Jan 07 NodeJs
详解nodejs中exports和module.exports的区别
Feb 17 NodeJs
详解nodejs爬虫程序解决gbk等中文编码问题
Apr 06 NodeJs
详解nodejs微信公众号开发——6.自定义菜单
Apr 13 NodeJs
Windows下快速搭建NodeJS本地服务器的步骤
Aug 09 NodeJs
nodejs 日志模块winston的使用方法
May 02 NodeJs
nodejs中方法和模块用法示例
Dec 24 NodeJs
nodejs检测因特网是否断开的解决方案
Apr 17 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
让你同时上传 1000 个文件 (二)
2006/10/09 PHP
兼容性最强的PHP生成缩略图的函数代码(修改版)
2011/01/18 PHP
PHP数组实例总结与说明
2011/08/23 PHP
Codeigniter中mkdir创建目录遇到权限问题和解决方法
2014/07/25 PHP
CI框架实现创建自定义类库的方法
2018/12/25 PHP
jquery实现的导航固定效果
2014/04/28 Javascript
jQuery Easyui Tabs扩展根据自定义属性打开页签
2016/08/15 Javascript
JS正则表达式学习之贪婪和非贪婪模式实例总结
2016/12/26 Javascript
Javascript快速实现浏览器系统通知
2017/08/26 Javascript
create-react-app安装出错问题解决方法
2018/09/04 Javascript
vue强制刷新组件的方法示例
2019/02/28 Javascript
layui table设置某一行的字体颜色方法
2019/09/05 Javascript
解决在layer.open中使用时间控件laydate失败的问题
2019/09/11 Javascript
原生js实现弹窗消息动画
2020/11/20 Javascript
[01:42]DOTA2 – 虚无之灵
2019/08/25 DOTA
python list转dict示例分享
2014/01/28 Python
将Python代码打包为jar软件的简单方法
2015/08/04 Python
Python 实现 贪吃蛇大作战 代码分享
2016/09/07 Python
python+selenium实现登录账户后自动点击的示例
2017/12/22 Python
django解决跨域请求的问题详解
2019/01/20 Python
Python3 修改默认环境的方法
2019/02/16 Python
Python+OpenCV采集本地摄像头的视频
2019/04/25 Python
Django 用户认证组件使用详解
2019/07/23 Python
详解如何用python实现一个简单下载器的服务端和客户端
2019/10/28 Python
解决Tensorflow 使用时cpu编译不支持警告的问题
2020/02/03 Python
python标准库sys和OS的函数使用方法与实例详解
2020/02/12 Python
Python计算IV值的示例讲解
2020/02/28 Python
Python描述符descriptor使用原理解析
2020/03/21 Python
PyCharm中关于安装第三方包的三个建议
2020/09/17 Python
浅析Python的命名空间与作用域
2020/11/25 Python
HTML5实现获取地理位置信息并定位功能
2015/04/25 HTML / CSS
卡骆驰英国官网:Crocs英国
2019/08/22 全球购物
西班牙购买隐形眼镜、眼镜和太阳镜网站:Lentiamo.es
2020/06/11 全球购物
计算机专业自荐信
2015/03/05 职场文书
2015年学校教务处工作总结
2015/05/11 职场文书
Redis实现一个账号只能登录一个设备
2022/04/19 Redis