javascript - setTimeout 是使用回调时避免 stackoverflow 的有效方法吗?

标签 javascript callback stack-overflow

假设我想创建一些回调 hell ,例如:

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 队列之外执行。

对吗?

最佳答案

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,但是在你的回调中使用超时(我不知道你是否可以这样做,因为我不知道你的回调是否会给你 future 的回调)你的最大值是 1,因为回调将在所有代码执行后单独执行(在它们自己的堆栈上)。

我觉得你打算这样写你的代码

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

这将再次导致深度为 6,除非您使用会导致堆栈大小为 1 的超时。

关于javascript - setTimeout 是使用回调时避免 stackoverflow 的有效方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22183271/

相关文章:

c - Linux 上 C 中的 GTK+ 3.0 : handle multiple calls of callback function by signals

parsing - scala 解析器组合器 stackoverflow 递归

Javascript:为什么最大堆栈大小似乎动态变化?

java - Android Spinner View : difference between setSelection (int position) and setSelection (int position, boolean 动画)?

javascript - 在更大的一组 radio 组中仅迭代特定的 radio 组

javascript - 在 AngularJS Controller 和服务之间共享资源

javascript - JQuery列表,防止链接被多次点击

javascript - Google maps API,回调是对象的方法

javascript - 仅在首页加载时运行 Javascript

express - 如何使用具有历史回退和 expressjs 路由的 vuejs 路由