为什么setTimeout是同步作用的?
Why is setTimeout acting synchronously?
setTimeout
的示例在它下面的同步代码之后被执行
console.log('hello');
setTimeout(() => console.log('timeout'), 0);
console.log('end');
控制台输出:
你好
结尾
超时
异步:
function asyncForEach(array, callBack) {
array.forEach(x => setTimeout(callBack(x), 0));
}
asyncForEach([1,2,3,4], (i) => console.log(i));
console.log('end');
控制台输出:
1
2
3
4
end
同步:
[1,2,3,4].forEach(x => console.log(x));
console.log('end');
控制台输出:
1
2
3
4
end
我试图更好地理解 event loop
和 task queue
,在观看了一个很好的推荐视频 (https://www.youtube.com/watch?v=8aGhZQkoFbQ) 之后,我发现了以下半语句:"Callbacks can be synchronous and asynchronous".演讲者继续演示同步方式如何不会最终通过 task queue
,因此不会通过 event loop
,所以一切都保留在 stack
上。但是,异步方式会导致 task queue
被 setTimeout
callback
的最终 return 填充,这将使自 [=16] 以来的任何同步代码都可执行=] 必须等待空 stack
才能插入 returned callback
.
当运行上面的代码(我从他那里偷来的,也编辑过的,所以可能是我的错误添加),异步方式产生与同步方式相同的结果。
谁能帮忙解释一下为什么异步方式不能作为第一个 setTimeout
示例 and/or 提供有关如何不将常规回调(例如数组辅助方法)插入到task queue
因此永远不会被 event loop
?
搞砸
您的 "asynchronous way" 不是异步的,因为您调用了该函数并将其 return 值传递给 setTimeout
:
function asyncForEach(array, callBack) {
array.forEach(x => setTimeout(callBack(x), 0)); // <-- callBack(x) calls callBack immediately
}
asyncForEach([1,2,3,4], (i) => console.log(i));
console.log('end');
如果你想延迟它,创建一个函数传递给 setTimeout
它可以稍后调用:
function asyncForEach(array, callBack) {
array.forEach(x => setTimeout(() => callBack(x), 0)); // <-- Makes closure that calls callBack(x) later
}
asyncForEach([1,2,3,4], (i) => console.log(i));
console.log('end');
您的 asyncForEach
函数中存在错误。您立即调用 callBack(x)
,然后将该函数 (undefined
) 的结果传递给 setTimeout
.
setTimeout
的示例在它下面的同步代码之后被执行
console.log('hello');
setTimeout(() => console.log('timeout'), 0);
console.log('end');
控制台输出: 你好 结尾 超时
异步:
function asyncForEach(array, callBack) {
array.forEach(x => setTimeout(callBack(x), 0));
}
asyncForEach([1,2,3,4], (i) => console.log(i));
console.log('end');
控制台输出:
1
2
3
4
end
同步:
[1,2,3,4].forEach(x => console.log(x));
console.log('end');
控制台输出:
1
2
3
4
end
我试图更好地理解 event loop
和 task queue
,在观看了一个很好的推荐视频 (https://www.youtube.com/watch?v=8aGhZQkoFbQ) 之后,我发现了以下半语句:"Callbacks can be synchronous and asynchronous".演讲者继续演示同步方式如何不会最终通过 task queue
,因此不会通过 event loop
,所以一切都保留在 stack
上。但是,异步方式会导致 task queue
被 setTimeout
callback
的最终 return 填充,这将使自 [=16] 以来的任何同步代码都可执行=] 必须等待空 stack
才能插入 returned callback
.
当运行上面的代码(我从他那里偷来的,也编辑过的,所以可能是我的错误添加),异步方式产生与同步方式相同的结果。
谁能帮忙解释一下为什么异步方式不能作为第一个 setTimeout
示例 and/or 提供有关如何不将常规回调(例如数组辅助方法)插入到task queue
因此永远不会被 event loop
?
您的 "asynchronous way" 不是异步的,因为您调用了该函数并将其 return 值传递给 setTimeout
:
function asyncForEach(array, callBack) {
array.forEach(x => setTimeout(callBack(x), 0)); // <-- callBack(x) calls callBack immediately
}
asyncForEach([1,2,3,4], (i) => console.log(i));
console.log('end');
如果你想延迟它,创建一个函数传递给 setTimeout
它可以稍后调用:
function asyncForEach(array, callBack) {
array.forEach(x => setTimeout(() => callBack(x), 0)); // <-- Makes closure that calls callBack(x) later
}
asyncForEach([1,2,3,4], (i) => console.log(i));
console.log('end');
您的 asyncForEach
函数中存在错误。您立即调用 callBack(x)
,然后将该函数 (undefined
) 的结果传递给 setTimeout
.