[JavaScript]对 MDN 上 queueMicrotask 的一段示例代码的理解
queueMicrotask
用于在微任务队列中添加一个微任务,从而保证代码在宏任务执行之前执行。
这篇文章中有一个批量发送消息的例子,代码如下:
const messageQueue = [];
let sendMessage = (message) => {
messageQueue.push(message);
if (messageQueue.length === 1) {
queueMicrotask(() => {
const json = JSON.stringify(messageQueue);
messageQueue.length = 0;
fetch("url-of-receiver", json);
});
}
};
包括 ChatGPT 在内的 AI 都不能正确解释这段代码的作用,MDN 上对这段代码的解释也比较难理解。
从表面上看,这段代码并没有什么难以理解的地方,但是,只有理解了 JavaScript 的任务队列、微任务、宏任务才能正确理解这段代码。
JavaScript 的任务队列分为两个:宏任务队列和微任务队列。JavaScript 执行完同步任务后,就会开始执行任务队列里的任务。主线程先检查微任务队列中是否有微任务,如果有,就执行它们,直到清空微任务队列,之后开始执行宏任务。与执行微任务不同的是,每执行完一个宏任务,就检查并执行、清空微任务。另外还有一个需要清楚的是,在执行微任务过程中,如果有新的微任务添加到微任务队列,JavaScript 会按顺序执行它们,直到清空微任务队列。
上面代码实现了消息的批量发送。当 messageQueue
的长度为 1
,也就是第一次调用 sendMessage
时,queueMicrotask
会创建一个微任务(这里用 f
指代这个微任务),添加到微任务队列的末尾。在执行到 f
之前的这段时间内,调用 sendMessage
只会向 messageQueue
中添加新消息,不会再创建微任务。当执行到 f
时,将会把 messageQueue
序列化成 JSON
,这个 json 包含了这段时间中添加到 messageQueue
中的所有消息,之后发送给服务器,并清空 messageQueue
,开始下一次循环。
End