javascriptsetTimeout and setIntervalزمانسنج در جاوااسکریپت
زمانسنج در جاوااسکریپت را با setTimeout، clearTimeout و setInterval بشناسید؛ تأخیر حداقلی، ترتیب اجرا و لغو کار برنامهریزیشده.
مفهوم به زبان ساده
setTimeout یک تابع را برای اجرای بعدی برنامهریزی میکند و شناسهای برای لغو آن میدهد. زمان بر حسب میلیثانیه است، اما تضمین زمان دقیق نیست. وقتی نوبت اجرای جاوااسکریپت آزاد شود و شرایط محیط اجازه دهد، callback میتواند اجرا شود. بنابراین تأخیر صفر هم به معنی اجرای فوری در میان دستورهای جاری نیست.
در نمونه، ابتدا یک زمانسنج میسازیم و پیش از اجرا لغوش میکنیم. سپس پیامهای همگام آغاز و پایان چاپ میشوند؛ در آخر callback زمانسنج صفر اجرا میشود. این ترتیب را با مدت دقیق اجرا اشتباه نگیرید. فعالیت سنگین همگام، وضعیت زبانهٔ پسزمینه یا سیاست مرورگر میتواند اجرا را عقب بیندازد؛ زمانسنج راه دورزدن مشغولبودن نخ اصلی نیست.
setInterval برای تکرار برنامهریزیشده است و با clearInterval متوقف میشود. اگر هر نوبت کار ناهمگام طولانی آغاز کند، پایان نوبت قبلی خودکار شرط شروع نوبت بعدی نیست. در چنین مسئلهای، زمانسنج بعدی پس از اتمام کار میتواند قرارداد روشنتری باشد. تابع را به زمانسنج بدهید، نه متن کد یا نتیجهٔ فراخوانی فوری آن. برای تمرین، فقط پیام زمانسنج لغوشده را تغییر دهید و توضیح دهید چرا در خروجی دیده نمیشود.
کجا به کار میآید؟
- نمایش پیام پس از یک فاصلهٔ حداقلی یا لغو کار زمانبندیشده
- کنترل تکرار آموزشی با نگهداری شناسه و مسیر توقف روشن
از تعریف تا یک مثال واقعی
const cancelled = setTimeout(() => console.log('نباید چاپ شود'), 0);
clearTimeout(cancelled);
console.log('آغاز');
setTimeout(() => console.log('بعداً'), 0);
console.log('پایان بخش همگام');
آغاز پایان بخش همگام بعداً
این مثال چطور کار میکند؟
زمانسنج نخست بلافاصله لغو میشود و پیام آن چاپ نمیشود.
دو دستور console.log همگام پیش از callback اجرا میشوند.
زمانسنج دوم پس از پایان بخش همگام فرصت اجرا پیدا میکند.
اشتباه رایج
setTimeout(task(), 1000) ابتدا task را همین حالا اجرا میکند. همچنین setInterval منتظر Promise کار قبلی نمیماند و تأخیر زمانسنج تضمین زمان دقیق نیست.
این را به خاطر بسپارید
زمانسنج، فرصت اجرای آینده را برنامهریزی میکند؛ شناسهٔ آن را برای توقف نگه دارید و زمان دقیق وعده ندهید.