了解使用 setTimeout 和 DOM Api 执行 WebAPI

Understanding execution of WebAPIs with setTimeout & DOM Api

我已经使用 JS 大约一年了,而且我仍在学习它。我的问题在最后。

在第一个例子中:

console.log('Start');

setTimeout(()=> console.log('inside callback'), 0); 

console.log('End');

产出

Start
End
inside callback

我明白了,虽然超时了0,但还是要到浏览器WebApi(setTimeoutapi),马上推入回调队列等待主线程空闲(当前正在执行 console.log('End'))。一旦线程空闲,就会执行回调并打印“内部回调”。

按照这种方法,我尝试用另一个 WebAPI 进行实验,即 DOM API。

这次,我没有使用setTimeout,而是使用了document.querySelectorAll()

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 输出没有出现在“结束”之后。

是否遵循了以下流程:

document.querySelectorAll -> webAPI -> 回调队列 -> 主线程

DOM API 是否必须通过回调队列并等待主线程为空如果是?与 setTimeout

不同,这次我们如何以正确的顺序获得控制台

我还在学习,非常感谢解释。如果我误解了,请指出任何事情。谢谢。

原因是 document.querySelectorAll 是同步方法,而 setTimeout 是异步方法。

JS 脚本在 DOM 所在的相同环境中执行,因此它不是异步的。异步事件是通常被发送到另一个环境的事件(稍后由事件循环处理)

这是基于事件循环的并发模型的一部分,它实际上负责执行代码,收集和处理事件。 setTimeout 函数使用 2 个参数调用:添加到回调队列的消息和时间值(可选;默认为 0)。时间值表示消息实际被推入队列的(最小)延迟。如果队列中没有其他消息,并且堆栈为空,则在延迟后立即处理该消息。但是,如果有消息,setTimeout 消息将不得不等待其他消息被处理,因此,第二个参数表示最短时间(不是保证时间)。因此,消息 'end' 将在回调 'inside callback' 中的消息得到处理之前写入控制台,因为延迟是运行时处理请求所需的最短时间(不是保证时间) .

document.querySelectorAll 是在 DOM 所在的同一环境中执行的脚本的一部分,因此它不是异步的,将立即执行。

DOM 操作是同步的。话虽如此,浏览器响应 DOM 更新的页面重新呈现过程是异步的。这会给人一种异步 DOM 更新的错觉。

更多关于 JavaScript 事件循环 - https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop