首页 > 解决方案 > Javascript 回调和堆栈溢出

问题描述

在处理回调嵌套时,我对 NodeJS/Javascript 的行为有疑问。

我在 NodeJS 应用程序中有以下(简化的)代码:

var request_list = [];

function doSomething(){
  if(request_list.length > 0){
    let r = request_list.shift();

    // Do something with r

    setTimeout( ()=> {doSomething()}, 1000);
  }
}

doSomething();

如果请求列表充满了很多请求,我们会不会出现堆栈溢出?

标签: javascriptnode.jscallback

解决方案


不,在这种情况下不会出现堆栈溢出。这是因为doSomething函数在调度自身执行后立即返回。

此外,每个doSomething函数都对同一个request_list对象进行操作,每次调用都会将其大小减小一,直到数组中没有元素为止,因此代码不可能无限期地运行。

我试图查看是否可能存在内存问题,因此我将您的示例推到了极限。

var request_list = new Array(10000).fill("a")
var start = Date.now();

function doSomething(){
  if(request_list.length > 0){
    let r = request_list.shift();

    console.log(r);
    // Do something with r

    setTimeout( ()=> {doSomething()}, 1);
  }
}

doSomething();

process.on('exit', () => { console.log('Total time: ' + (Date.now() - start))})

我创建了一个包含 10000 个元素的数组,其中 asetTimeout为 1 ms。该过程在Total time: 148020(大约 148 秒)内完成,可能是由于昂贵的数组移位和 console.log 调用。在此期间,总内存node保持不变,因此也没有问题。


推荐阅读