【问题标题】:Are "Event Loop" and "Event Queue" the same in JavaScript?JavaScript 中的“事件循环”和“事件队列”是否相同?
【发布时间】:2021-01-16 23:38:11
【问题描述】:

我是 JavaScript 新手,想知道“JS”如何处理异步操作。我开始知道它是在“事件循环”和“事件队列”的帮助下完成的,但我不知道有什么区别。谁能帮帮我。

asynchronous operations 的示例可以是:

function alpha(){
  setTimeout(() => alert("hi"), 3000);
};

alpha();

【问题讨论】:

标签: javascript html css ecmascript-6


【解决方案1】:

事件循环是浏览器(或其他 JavaScript 主机)运行的循环,从 事件队列(更一般地说是一个 job task 队列,该队列列出等待处理的事件/作业/任务)并处理它,然后返回下一个并处理它,等等。 p>

用伪代码术语(省略很多细节):

// Event/job/task loop:
while (running) {
    const task = taskQueue.pop();
    if (task) {
        task();
    }
}

JavaScript 代码或主机环境事件可能会将作业/任务添加到队列中,以便在循环到达它们时将其拾取。

HTML 规范详细介绍了进程here。乍一看,在 HTML 规范中包含这些信息似乎很奇怪,但该规范不仅描述了 HTML(标记语言),还描述了用户代理(包括浏览器)应如何处理/呈现网页。

JavaScript 规范讨论了这个here,尽管它没有详细说明主机应该执行什么样的循环,因为这是特定于主机的。

作为非浏览器 JavaScript 主机的示例,Node.js 文档描述了它的循环 here


上面的伪代码中遗漏的一个更重要的细节是,几乎所有 JavaScript 主机中都至少有 两个 队列:主要的一个(被 HTML 规范称为“任务队列”) ) 和一个用于承诺反应和可选的其他事情(被 HTML 规范称为“微任务队列”)。所以这个工作循环看起来更像:

// Event/job/task loop:
while (running) {
    const task = taskQueue.pop();
    if (task) {
        task();
        // Microtask loop:
        while (!microtaskQueue.isEmpty()) {
            const microtask = microtaskQueue.pop();
            microtask();
        }
    }
}

注意微任务队列是如何在每个任务之后清空的,这意味着如果任务队列中有任务 1、任务 2 和任务 3,并且在任务 1 的处理过程中,微任务队列中会添加两个微任务,这些微任务在任务 1 结束时运行,在任务 2 之前。这是一个示例:setTimeout 将任务排队,但承诺反应(调用履行或拒绝处理程序)是微任务:

// Task 1
console.log("Queuing Task 1");
setTimeout(() => {
    console.log("Task 1 - start");
    // Note: The promise handling below is atypical, tailored specifically to
    // this example. Normally you chain promises, and you handle rejections.
    // Note that the below says we're "queuing Microtask X" because we know
    // that the promise is already fulfilled. Normally, when you call `then`,
    // you *don't* know whether the promise is fulfilled yet, so the microtask
    // may be added when you call `then`, or may be added later when the
    // promise is fulfilled
    const p = Promise.resolve();
    console.log("Task 1 queuing Microtask A");
    p.then(() => {
        console.log("Microtask A");
    });
    console.log("Task 1 queuing Microtask B");
    p.then(() => {
        console.log("Microtask B");
    });
    console.log("Task 1 - end");
}, 0);

// Task 2
console.log("Queuing Task 2");
setTimeout(() => {
    console.log("Task 2");
}, 0);

// Task 3
console.log("Queuing Task 3");
setTimeout(() => {
    console.log("Task 3");
}, 0);
.as-console-wrapper {
    max-height: 100% !important;
}

【讨论】:

    猜你喜欢
    • 2020-02-11
    • 2018-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-03
    • 2013-04-14
    • 1970-01-01
    相关资源
    最近更新 更多