闽公网安备 35020302035485号
                | 角色 | 类比 | 
|---|---|
| 调用栈 Call Stack | 烤串师傅(一次只能烤一串) | 
| 宏任务队列 Macrotask Queue | 外卖订单(setTimeout、I/O、UI 渲染) | 
| 微任务队列 Microtask Queue | 加急小票(Promise、queueMicrotask、MutationObserver) | 
document.getElementById('saveButton').addEventListener('click', async () => {
  updateLoadingState(true);          // 1. 立刻转菊花
  try {
    await saveUserData(userData);    // 2. 异步保存
    showSuccessMessage('保存成功');  // 3. 微任务里更新 UI
    const data = await fetchUser();  // 4. 再拿新数据
    updateUI(data);                  // 5. 再更新 UI
  } catch (e) {
    showErrorMessage(e.message);     // 6. 出错兜底
  } finally {
    updateLoadingState(false);       // 7. 关闭菊花
  }
});
菊花之所以能立刻转起来,是因为 updateLoadingState(true) 是同步的。queueMicrotask(() => {
  console.log('我是加急,宏任务都靠边!');
});
与 setTimeout(fn, 0) 的区别:setTimeout 是宏任务,得等渲染;queueMicrotask 是微任务,马上跑。class ThemeManager {
  constructor() {
    this.theme = { darkMode: false, contrast: 'normal', fontSize: 16 };
    this.isRendering = false;
  }
  // 堆代码 duidaima.com
  updateTheme(updates) {
    // 1. 改数据
    this.theme = { ...this.theme, ...updates };
    // 2. 只排一次队,避免多次重排
    if (!this.isRendering) {
      this.isRendering = true;
      queueMicrotask(() => {
        this.applyThemeToDOM();
        this.isRendering = false;
      });
    }
  }
  applyThemeToDOM() {
    document.documentElement.style.setProperty(
      '--bg',
      this.theme.darkMode ? '#1a1a1a' : '#fff'
    );
  }
}
const tm = new ThemeManager();
tm.updateTheme({ darkMode: true });
tm.updateTheme({ contrast: 'high' });
tm.updateTheme({ fontSize: 20 });
// 最终只调用一次 applyThemeToDOM,性能拉满!
FormController:表单提交不抖屏class FormController {
  constructor(formEl) {
    this.form = formEl;
    this.isSubmitting = false;
    this.form.addEventListener('submit', async (e) => {
      e.preventDefault();
      if (this.isSubmitting) return;
      this.setSubmitting(true);
      try {
        const res = await fetch('/api/submit', { method: 'POST', body: new FormData(this.form) });
        if (!res.ok) throw new Error(res.statusText);
        // 用微任务确保状态更新后再提示用户
        queueMicrotask(() => {
          this.showSuccess();
          this.resetForm();
        });
      } catch (err) {
        this.showError(err);
      } finally {
        this.setSubmitting(false);
      }
    });
  }
  setSubmitting(flag) {
    this.isSubmitting = flag;
    this.form.querySelector('button[type="submit"]').disabled = flag;
  }
}
微任务 vs Promise:谁先谁后?console.log('Script start');
setTimeout(() => console.log('setTimeout'), 0);
queueMicrotask(() => {
  console.log('Microtask 1');
  queueMicrotask(() => console.log('Nested Microtask 1'));
});
Promise.resolve()
  .then(() => {
    console.log('Promise 1');
    queueMicrotask(() => console.log('Nested Microtask 2'));
  })
  .then(() => console.log('Promise 2'));
queueMicrotask(() => console.log('Microtask 2'));
console.log('Script end');
/*
输出顺序:
Script start
Script end
Microtask 1
Promise 1
Microtask 2
Nested Microtask 1
Promise 2
Nested Microtask 2
setTimeout
*/
口诀:“清完微任务,才轮到宏任务”。function infiniteMicrotask() {
  queueMicrotask(infiniteMicrotask); // 卡死循环,浏览器直接罢工
}
2. 微任务里干重活 → 阻塞渲染queueMicrotask(() => {
  // 千万别算大斐波那契,UI 会冻成狗
});
3. 与宏任务混用 → 顺序谜之混乱| 特性 | JS 微任务 | Go defer | 
|---|---|---|
| 触发时机 | 当前同步栈清空后 | 函数 return 前 | 
| 执行顺序 | FIFO(队列) | LIFO(栈) | 
| 异步? | ✅ 是 | ❌ 否 | 
| 典型用途 | UI 批处理/状态同步 | 文件关闭/锁释放 | 
3.断点:直接在 .then 或 queueMicrotask 回调里打断点,看闭包变量。
	
.时间敏感动画(交给 requestAnimationFrame)