标签 任务队列 下的文章

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