gpt4 book ai didi

javascript - 事件循环什么时候开始?

转载 作者:行者123 更新时间:2023-12-03 02:58:39 26 4
gpt4 key购买 nike

我对事件循环何时在浏览器中旋转感到有点困惑。

问题是:

  • 任务和待处理的微任务是否发生在同一循环迭代/轮次/滴答中?
  • 环路转动需要满足哪些实际条件?
  • 这些条件在 Node.js 事件循环中是否相同? - 我不知道这是否是一个愚蠢的问题。

假设我们有一个网页,在前端中,我们有 JavaScript 代码来安排任务并等待 promise (这是一个微任务)。 Promise 的执行是否被认为发生在与任务相同的事件循环轮次中,或者不同的迭代中?

我目前假设它们都发生在同一次迭代中。因为如果否则的话,在微任务在任务中间执行的情况下,这意味着该任务需要多次循环迭代才能完全完成。这对我来说似乎很重要。说每个任务之后可能发生的更新渲染部分发生在同一个循环回合中是否正确?

提前谢谢您!

------------------------------------------------------------ --------------------------------------------------

我知道我应该添加一条评论,但它会很长,而且我还需要编写代码,所以我正在编辑问题并要求澄清。

@T.J. Crowder 非常感谢您的宝贵时间和详细解释!

我确实误读了 this great article 中的“微任务在回调后处理(只要没有其他 JavaScript 处于执行中)”并且有点困惑。

我还对 4ms setTimout 有疑问,但我找不到相关信息,所以也感谢您提供这些信息。

最后一件事...如果我们要标记示例代码之间的循环刻度,我们会将它们放在哪里(假设 console.logs 不存在)?

假设我们有一个名为 exampleCode 的函数,其主体如下:

setTimeout(setTimeoutCallback, 0);
Promise.resolve().then(promiseCallback);

对于上面的代码,我的猜测是......

在执行 exampleCode(宏)任务之前:

  • 第一个循环刻度
  • setTimeoutCallback(宏)任务调度
  • Promise.then 微任务调度
  • promise回调执行
  • 第二个循环刻度
  • setTimeoutCallback执行
  • 第三个循环刻度

或者在Promise.then微任务调度promiseCallback执行之间是否存在额外的循环标记?

再次预先感谢您!

最佳答案

Does a task and the pending microtasks, happen in the same loop iteration/turn/tick?

任务发生,然后当它结束时,它安排的任何挂起的微任务都会运行。

Which are the actual conditions that need to be met in order for the loop to turn?

不清楚你的意思。从作业作业队列(这是 ECMAScript 规范的术语)的 Angular 来思考可能会更容易:如果有一个挂起的作业并且为该队列提供服务的线程是不做其他事情,它就会拿起作业并运行它直至完成。

Are these conditions the same in node.js event loop?

足够接近了,是的。

Let's say we have a webpage and in the front end we have JavaScript code that schedules a task and waits for a promise (which is a microtask). Is the execution of the promise considered to happen in the same turn of the event loop as the task, or in different iterations?

在浏览器(和 Node)中,它发生在任务完成之后,当任务的微任务(如果有)运行时,在下一个排队的任务/作业被拾取之前。

例如:

// This code is run in a task/job

console.log("Scheduling (macro)task/job");
setTimeout(() => {
console.log("timeout callback ran");
}, 0);

console.log("Scheduling microtask/job");
Promise.resolve().then(() => {
console.log("promise then callback ran");
});

console.log("main task complete");

在兼容的浏览器(和 Node)上,将输出:

Scheduling (macro)task/jobScheduling microtask/jobmain task completepromise then callback rantimeout callback ran

...because the microtask ran when the main task completed, before the next macrotask ran.

(Note that setTimeout(..., 0) will indeed schedule the timer to run immediately on compliant browsers provided it's not a nested timeout; more here. You'll see people saying there is no "setTimeout 0", but that's outdated information. It's only clamped to 4ms if the timer's nesting level is > 5.)

More to explore:


Re the code and question in the edit/comment:

setTimeout(setTimeoutCallback, 0);
Promise.resolve().then(promiseCallback);

你的猜测看起来不错。我是这样描述的:

  1. 安排任务来运行该脚本
  2. (当线程下次空闲时)
    1. 开始下一个任务(从上面的#1开始)
    2. 运行该任务:
      1. 为计时器回调创建任务
        • 并行地,在时间到来时将任务排队
      2. 将微任务排队以供 Promise then 回调
      3. 任务结束
    3. 微任务检查
      • 运行then回调
  3. (当线程下次空闲时)
    1. 开始下一个任务(计时器回调的任务)
    2. 运行任务
    3. 任务结束
    4. 微任务检查(在这种情况下无需执行)

处理模型文本明确指出任务在微任务检查之前结束,但我认为这无法以任何实际方式观察到。

关于javascript - 事件循环什么时候开始?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47508649/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com