2016-01-09 51 views
0

所以,我想运行一个intervaled功能时,但有一个递归超时:避免堆栈溢出运行递归超时

var runUpdater = function() { 
    setTimeout(() => { 
    console.log('something here') 
    runUpdater() 
    }, 1000) 
} 

这将体现在将始终为长期服务运行时间。我认为这最终会出现堆栈溢出,对吗?我的问题是:避免它的最好方法是什么?

+0

代码中没有递归 - >“问题”解决:) – Andreas

+1

'setInterval()'怎么样? – ne1410s

回答

1

不,不会有堆栈溢出。每次调用setTimeout都会在事件循环中排队一条新消息。当执行setTimeout回调函数时,你会得到一个全新的堆栈,深度为1,当执行线程完成时它将不再存在。例如,下面将迅速抛出达到最大堆栈大小时,引发RangeError:

try { 
 
    !function func () { 
 
     func(); 
 
    }(); 
 
} catch (e) { 
 
    document.body.innerHTML = e.message; 
 
}

但这个版本不会有任何问题无限期地运行:

try { 
 
    !function func () { 
 
     setTimeout(func, 0); 
 
    }(); 
 
} catch (e) { 
 
    document.body.innerHTML = e.message; 
 
}

1

经过一些测试后,我认为您的当前代码没有递归。由于runUpdater()在执行内部runUpdater()后立即退出。 setTimeout()调用并不会阻止浏览器的主线程,而是当浏览器空闲时安排您的函数调用,然后立即退出(随后终止调用者,因此不会发生递归)

我宁愿使用setInterval()你的情况为可读性的原因,避免recursive调用任何混乱:(!感谢)的基础上通过@Paulpro作出评论

setInterval(function() { 
    console.log('something here'); 
}, 1000); 

编辑:

我认为setInterval确实与相同与延迟和调用相同的功能,但它并没有,setTimeout的运行顺序,当你的函数调用runUpdater()setInterval只是时间表忽略了功能的状态被称为

TL只安排下一次调用; DR:使用他的版本的答案

+0

请注意,如果setInterval运行的代码比运行它(甚至是异步)之间的延迟时间更长,将会导致问题,因为它将继续排队越来越多的回调并进一步落后。如果每次都发出Ajax请求,那可能会非常糟糕。您可以很容易地达到您的浏览器一次发送的最大请求数,然后在其上建立一个大队列,并且如果您在别处发送任何其他Ajax请求,他们将不会长时间发送。 – Paulpro

+0

@Paulpro指出,谢谢。 –