使用回调时,setTimeout是否有效避免stackoverflow?

时间:2014-03-04 21:19:07

标签: javascript callback stack-overflow

说我想创建一些回调地狱,例如:

function handleUserInput(callback) {
    ...
} 

function get(uri, callback) {
    ...
}

function processResponseInWorker(callback) {
    ....
}

function updateIndexedDB(callback) {
    ...
}

function updateUI() {
    ...
} 

handleUserInput(get(hot_uri,processResponseInWorker(updateIndexedDB(updateUI()))));

这主要是学术性的,因为筹码只有5个高。

事实上,甚至还有堆栈吗?由于这些调用将立即返回,并且仅在这些上下文之外调用回调,这些函数执行的任何异步任务。

好吧,只是说这里有一个调用堆栈,如果每个回调都被强制在setTimeout(func,0)内执行,那么调用函数会立即返回,整个链将立即返回并且函数将被执行掉setTimout queue。

这是对的吗?

1 个答案:

答案 0 :(得分:2)

除非没有其他代码在运行,否则

setTimeout将不会调用提供的函数。

正如在this code中所证明的那样,超时虽然是0毫秒延迟,但在没有其他代码执行之前不会执行。这是经典javascript(同步)的本质。

console.log(1);
setTimeout(function() {
    console.log(2);
}, 0);
console.log(3);
for(var i = 4; i < 100; i++) {
    console.log(i);
}

最初假设深度为0.让我们假设除了回调和原始代码中的函数之外没有其他函数被调用

updateUI()

调用函数updateUI我们的深度变为1.我们从这个函数返回一个函数,我们的深度再次变为0,我们有一些基本上是这样的东西。

updateIndexedDB(function(){})

所以我们调用updateIndexedDB,我们的深度变为1,调用提供的回调函数,深度变为2.回调返回,深度变为1,updateIndexedDB返回函数,以便我们看起来像像这样。

processResponseInWorker(function() {})

类似的过程发生在我们有这个

之前
get(hot_uri, function() {})

直到我们有了这个

,同样的事情
handleUserInput(function() {})

在没有使用超时的情况下,我观​​察到的最大深度是2但是在你的回调上使用了超时(我不知道你能做什么,因为我不知道你的回调是否会给你未来的回调)你的最大值是1,因为在所有代码执行完后(在他们自己的堆栈上),将单独执行回调。

我觉得你打算以这种方式编写代码

handleUserInput(function() {
    get(hot_uri , function() {
        processResponseInWorker(function() {
            updateIndexedDB(function() {
                updateUI();
            });
        });
    });
});

除非你使用导致堆栈大小为1的超时,否则将导致深度为6。