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] → اجرا میشهدو نوع صف:
| نوع | مثال | اولویت |
|---|---|---|
| Microtask | Promise.then, queueMicrotask, MutationObserver | اول اجرا میشه |
| Macrotask | setTimeout, setInterval, click | بعد از میکروتسکها |
queueMicrotask vs setTimeout(..., 0)
| ویژگی | queueMicrotask | setTimeout(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 رو بلاک کنه |