JavaScript 的任务调度机制

JavaScript 的任务调度机制是基于 事件循环(Event Loop) 的,它管理了不同类型的任务队列。总的来说,任务调度机制涉及到三种主要的任务队列:

  1. 同步任务(Synchronous Tasks)
  2. 微任务(Microtasks)
  3. 宏任务(Macrotasks)

在某些情况下,我们还可以提到 交互队列延迟队列,它们可以视为宏任务的一部分。以下是它们的详细介绍、执行顺序和示例:

1. 同步任务(Synchronous Tasks)

  • 同步任务是指代码中按顺序执行的任务。这些任务会先被执行,直到执行栈清空。
  • 特点:同步任务是JavaScript执行的主要任务,必须按顺序执行,无法中断。

执行顺序:

  • 同步任务先执行。

示例:

console.log('Start');
console.log('End');

输出顺序:

Start
End

2. 微任务(Microtasks)

微任务是指那些在同步任务执行完后、下一个宏任务开始前执行的任务。微任务的优先级比宏任务高,因此它们会在当前栈清空后立刻执行。

  • 常见的微任务

    • Promise.then().catch().finally() 回调
    • queueMicrotask()
    • MutationObserver

执行顺序:

  • 执行同步任务。
  • 执行所有微任务,直到微任务队列清空。
  • 然后才会开始执行宏任务。

示例:

console.log('Start');

setTimeout(() => {
    console.log('Timeout 1');
}, 0);

Promise.resolve().then(() => {
    console.log('Promise 1');
});

setTimeout(() => {
    console.log('Timeout 2');
}, 0);

Promise.resolve().then(() => {
    console.log('Promise 2');
});

console.log('End');

输出顺序:

Start
End
Promise 1
Promise 2
Timeout 1
Timeout 2
  • 执行过程

    • 先执行同步代码:StartEnd
    • 然后执行微任务队列中的任务:Promise 1Promise 2
    • 最后执行宏任务队列中的任务:Timeout 1Timeout 2

3. 宏任务(Macrotasks)

宏任务包括所有的异步任务和UI更新任务。它们的执行顺序是按队列顺序来执行的,每次执行一个宏任务。

  • 常见的宏任务

    • setTimeoutsetInterval
    • I/O 操作(例如文件读取、网络请求等)
    • 用户交互事件(点击、键盘输入等)

执行顺序:

  • 执行同步任务。
  • 执行所有微任务。
  • 执行宏任务(例如 setTimeout、事件监听等)。

示例:

setTimeout(() => {
    console.log("Timeout 1");
}, 0);

setTimeout(() => {
    console.log("Timeout 2");
}, 0);

console.log("Start");

输出顺序:

Start
Timeout 1
Timeout 2
  • 执行过程

    • 先执行同步代码:Start
    • 然后执行宏任务队列中的任务:Timeout 1Timeout 2

4. 交互队列(Interaction Queue)

交互队列包含与用户交互相关的事件,如点击、输入框事件等。这些事件会作为宏任务的一部分,通常是在宏任务执行后、微任务执行前执行。

  • 常见的交互队列事件

    • clickkeydowninput 等。

执行顺序

  • 宏任务中的异步任务完成后,事件循环会处理交互队列中的任务。

示例:

document.body.addEventListener('click', () => {
    console.log('Click event');
});

执行过程

  • 用户点击页面后,点击事件会被加入到交互队列,并在下一轮事件循环中执行。

5. 延迟队列(Delayed Queue)

延迟队列实际上是宏任务队列的一部分,专门处理带有延迟时间的任务(如 setTimeoutsetInterval)。这些任务会在延迟时间到期后进入队列,并作为宏任务执行。

  • 常见的延迟队列任务

    • setTimeoutsetInterval

执行顺序

  • 延迟队列的任务是宏任务的一部分,会在当前宏任务执行完后、下一个宏任务之前执行。

示例:

setTimeout(() => {
    console.log('Delayed Timeout');
}, 1000);

执行过程

  • 任务会在大约 1000 毫秒后被加入宏任务队列。

总结:JavaScript 任务调度机制的队列

JavaScript 主要通过事件循环管理不同的任务队列,每种队列的任务执行顺序如下:

  1. 同步任务:首先执行,执行栈中的代码。
  2. 微任务队列:在同步任务执行后、宏任务之前执行。优先级较高。
  3. 宏任务队列(包含延迟队列):在微任务执行完后执行。宏任务包含 setTimeoutsetInterval 等异步任务。
  4. 交互队列:处理与用户交互相关的事件,通常在宏任务和微任务之间执行。

执行流程:

  1. 执行同步任务。
  2. 执行所有微任务,直到微任务队列为空。
  3. 执行交互队列中的任务。
  4. 执行宏任务队列中的任务(如延迟队列中的 setTimeout 回调)。

示例总结:

console.log("Start");

setTimeout(() => {
    console.log("Timeout 1");
}, 0);

Promise.resolve().then(() => {
    console.log("Promise 1");
});

document.body.addEventListener('click', () => {
    console.log("Click Event");
});

setTimeout(() => {
    console.log("Timeout 2");
}, 0);

console.log("End");

输出顺序:

Start
End
Promise 1
Timeout 1
Click Event
Timeout 2

事件循环在处理任务时,会先执行同步代码,然后清空微任务队列,接着处理交互队列中的任务,再执行宏任务队列中的任务。

JavaScript

我来吐槽

*

*

已有 31 条评论

  1. Vincentfreft

    The application is available for Android and iOS, providing quick access to the gameplay. Simple installation and user-friendly interface will make the game comfortable, and the mobile version will allow you to enjoy gambling entertainment anywhere ?????? Banda ???????????

  2. EddieMuh

    The authorization process at Arkada Casino is as simple as possible. The player needs to enter an email and password, after which he gets access to his personal account бездепозитный бонус Arkada casino

  3. OscarVal

    ТОП-10 лучших сервисов для WhatsApp-рассылки WhatsApp является одним из самых популярных мессенджеров в мире, с миллиардами активных пользователей https://marketing-i.ru/

  4. TestUser

    YkY ERwjdj gDsMI NCV aSL fAWF

  5. Robertgeque

    https://avtoznak-dublikat.ru/

  6. https://www.cucumber7.com/
    https://www.cucumber7.com/ April 8th, 2025 at 10:38 pm 回复

    Thanks very interesting blog!

  7. online medicine order discount
    online medicine order discount April 7th, 2025 at 08:22 am 回复

    Howdy! This is kind of off topic but I need some help from an established blog.
    Is it tough to set up your own blog? I'm not very techincal but I
    can figure things out pretty fast. I'm thinking about setting up my own but
    I'm not sure where to start. Do you have any ideas or suggestions?
    With thanks

  8. John

    TDABurrX ATD lwltAs JVKH