queueMicrotask یک API مدرن در جاوااسکریپت (و TypeScript) هست که یک تابع رو در انتهای میکروتسک‌ها (microtask queue) قرار می‌ده.

queueMicrotask(() => {
  console.log('این بعد از رندر، اما قبل از paint اجرا میشه');
});

Event Loop در جاوااسکریپت (یادآوری)

جاوااسکریپت از Event Loop استفاده می‌کنه:

MacroTask Queue        ← setTimeout, setInterval, DOM events, I/O
     ↑
     └───► [Call Stack] ───► MicroTask Queue ───► render/paint
                   ↑            (Promise.then, queueMicrotask)
                   └───► [empty] → اجرا میشه

دو نوع صف:

نوعمثالاولویت
MicrotaskPromise.then, queueMicrotask, MutationObserverاول اجرا میشه
MacrotasksetTimeout, setInterval, clickبعد از میکروتسک‌ها

queueMicrotask vs setTimeout(..., 0)

ویژگیqueueMicrotasksetTimeout(0)
اجراقبل از رندر بعدیبعد از رندر بعدی
سرعتخیلی سریعکندتر
استفادهکارهای فوری بعد از کد فعلیکارهای تأخیری
مثالPromise.resolve().then(...)setTimeout(() => {}, 0)
console.log('1');

queueMicrotask(() => console.log('2'));  // میکروتسک

setTimeout(() => console.log('3'), 0);   // مکروتسک

console.log('4');

// خروجی: 1 4 2 3

کی از queueMicrotask استفاده کنیم؟

1. بعد از تغییر DOM، قبل از رندر

element.textContent = 'جدید';

queueMicrotask(() => {
  console.log('DOM تغییر کرد، حالا اندازه بگیر:', element.offsetWidth);
});

offsetWidth درست خونده میشه، چون مرورگر هنوز رندر نکرده.

2. جایگزین Promise.resolve().then()

// قبلاً:
Promise.resolve().then(() => doSomething());

// حالا (تمیزتر و سریعتر):
queueMicrotask(() => doSomething());

3. در Angular: بعد از تغییر سیگنال، قبل از CD

this.loading.set(true);

queueMicrotask(() => {
  // اینجا مطمئنی DOM آپدیت شده
  this.scrollToTop();
});

4. رفع ExpressionChangedAfterItHasBeenCheckedError (NG0100)

مثلاً در کامپوننت:

ngAfterViewInit() {
  this.show = true; // تغییر در CD

  queueMicrotask(() => {
    this.show = false; // تغییر در میکروتسک → خطا نمی‌ده
  });
}

queueMicrotask تغییر رو بعد از چک Angular انجام می‌ده → خطای NG0100 نمیاد.

کی نباید از queueMicrotask استفاده کرد؟

موردچرا نه؟
انیمیشن یا اسکرولنیاز به requestAnimationFrame داره
تأخیر واقعیاز setTimeout استفاده کن
کارهای سنگینممکنه UI رو بلاک کنه