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极简入门教程(三):进程
Oct 27 NodeJs
Nodejs学习笔记之Global Objects全局对象
Jan 13 NodeJs
Nodejs学习笔记之NET模块
Jan 13 NodeJs
NodeJS学习笔记之MongoDB模块
Jan 13 NodeJs
NodeJS中利用Promise来封装异步函数
Feb 25 NodeJs
nodejs简单实现操作arduino
Sep 25 NodeJs
Ajax异步文件上传与NodeJS express服务端处理
Apr 01 NodeJs
Nodejs--post的公式详解
Apr 29 NodeJs
nodejs制作爬虫实现批量下载图片
May 19 NodeJs
nodejs 日志模块winston的使用方法
May 02 NodeJs
webpack打包nodejs项目的方法
Sep 26 NodeJs
nodejs使用Sequelize框架操作数据库的实现
Oct 21 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
CURL状态码列表(详细)
2013/06/27 PHP
PHP中使用正则表达式提取中文实现笔记
2015/01/20 PHP
Laravel 5框架学习之模型、控制器、视图基础流程
2015/04/08 PHP
php 的多进程操作实践案例分析
2020/02/28 PHP
JScript内置对象Array中元素的删除方法
2007/03/08 Javascript
js 获取radio按钮值的实例
2013/08/17 Javascript
基于jquery实现的省市区级联无ajax
2013/09/24 Javascript
javascript删除option选项的多种方法总结
2013/11/22 Javascript
jQuery中[attribute!=value]选择器用法实例
2014/12/31 Javascript
可以浮动某个物体的jquery控件用法实例
2015/07/24 Javascript
微信小程序 MINA文件结构
2016/10/17 Javascript
javascript iframe跨域详解
2016/10/26 Javascript
jQuery插件扩展操作入门示例
2017/01/16 Javascript
用React实现一个完整的TodoList的示例代码
2017/10/30 Javascript
webpack配置导致字体图标无法显示的解决方法
2018/03/06 Javascript
jQuery仿移动端支付宝键盘的实现代码
2018/08/15 jQuery
JS 数组随机洗牌的实例代码
2018/09/12 Javascript
一步一步实现Vue的响应式(对象观测)
2019/09/02 Javascript
微信小程序跨页面传递data数据方法解析
2019/12/13 Javascript
[43:49]LGD vs CHAOS 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/16 DOTA
python监控键盘输入实例代码
2018/02/09 Python
Pandas 合并多个Dataframe(merge,concat)的方法
2018/06/08 Python
Python实现简单层次聚类算法以及可视化
2019/03/18 Python
PythonWeb项目Django部署在Ubuntu18.04腾讯云主机上
2019/04/01 Python
python3 字符串/列表/元组(str/list/tuple)相互转换方法及join()函数的使用
2019/04/03 Python
Python3内置模块之base64编解码方法详解
2019/07/13 Python
使用Python制作表情包实现换脸功能
2019/07/19 Python
Python3 sys.argv[ ]用法详解
2019/10/24 Python
露营世界:Camping World
2017/02/02 全球购物
波兰购物网站:MALL.PL
2019/05/01 全球购物
互联网创业计划书写作技巧攻略
2014/03/23 职场文书
私人会所最新创业计划书范文
2014/03/24 职场文书
精神文明建设先进工作者事迹材料
2014/05/02 职场文书
班组拓展活动方案
2014/08/14 职场文书
销售督导岗位职责
2015/04/10 职场文书
Apache POI的基本使用详解
2021/11/07 Servers