假设我想创建一些回调 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/