【发布时间】:2022-01-08 19:22:20
【问题描述】:
我已经使用 JS 大约一年了,我还在学习它。我的问题在最后。
在第一个例子中:
console.log('Start');
setTimeout(()=> console.log('inside callback'), 0);
console.log('End');
输出
Start
End
inside callback
我知道即使超时是0,它仍然必须转到浏览器WebApi(setTimeout api)并立即推入回调队列等待主线程空闲(当前正在执行console.log( '结尾'))。一旦线程空闲,就会执行回调并打印“内部回调”。
按照这种方法,我尝试用另一个 WebAPI 即 DOM API 来试验它。
这一次,我使用 document.querySelectorAll() 代替 setTimeout
console.log('Start');
console.log(document.querySelectorAll('img'))
console.log('End');
输出
Start
NodeList(4) [img.bar-sm.-avatar.js-avatar-me, img.bar-sm.avatar.s-avatar--image, img, img]
End
这一次我们在 END 打印之前看到 DOM API 输出。
我知道输出,但我想了解其背后的流程。
为什么不遵循 setTimeout 之类的模式?
如果在单独的线程上处理,为什么 DOM 输出没有出现在“End”之后。
是否遵循以下流程:
document.querySelectorAll -> webAPI -> 回调队列 -> 主线程
DOM API 是否必须通过回调队列并等待主线程为空。 如果是这样?为什么我们这次的控制台顺序与 setTimeout 不同
我仍在学习,非常感谢您的解释。如果我误解了,请指出任何内容。谢谢。
【问题讨论】:
-
setTimeout()在timeoutms 之后将回调推送到将被先进先出处理的queue。.querySelectorAll()立即执行。 -
是的,我的最佳解释是因为 querySelectorAll 是同步的,而 setTimeout 是异步的。对吗?
-
setTimeout()本身也是同步的。但它会触发一个异步操作,即将提供的回调添加到稍后处理的队列中。 -
“setTimeout() 本身也是同步的”我不确定你的意思。 developer.mozilla 提到“setTimeout() 是一个异步函数,这意味着计时器函数不会暂停函数堆栈中其他函数的执行。” developer.mozilla.org/en-US/docs/Web/API/setTimeout
-
抱歉,我在这里可能有点挑剔...
/* code/statement A */; setTimeout(); /* code/statement B */;将始终以相同的顺序执行:A->setTimeout()->B,因为那部分是同步的。但是回调,setTimeout()调用的预定部分,会在稍后时间执行 -> 异步。所以说setTimeout()是异步的(几乎)是正确的,因为它的相关部分(回调)实际上是异步的。
标签: javascript dom settimeout event-loop