javascriptSynchronous and asynchronous executionاجرای همگام و ناهمگام در جاوااسکریپت
تفاوت اجرای همگام و ناهمگام در جاوااسکریپت را با callback فوری و زمانبندیشده ببینید؛ ترتیب خروجی و معنی واقعی تأخیر صفر را بشناسید.
مفهوم به زبان ساده
در اجرای همگام، هر کارِ همان مسیر باید تمام شود تا دستور بعدی ادامه پیدا کند. حتی اگر آن کار را به تابع دیگری ببریم، خودِ تابعبودن آن را ناهمگام نمیکند. در کار ناهمگام، برنامه میتواند عملیاتی را آغاز کند و ادامهٔ رسیدگی به نتیجه را برای بعد قرار دهد. نباید برای رسیدن پاسخ، حلقهای همگام بسازیم که رابط را مشغول نگه دارد.
مثال دو callback دارد. runNow تابع دادهشده را همان لحظه فراخوانی میکند، پس پیام همگام میان شروع و پایان چاپ میشود. setTimeout کار دیگری را زمانبندی میکند؛ آن callback پس از پایان کد همگام فعلی فرصت اجرا پیدا میکند. به همین دلیل «بعدتر» در آخر دیده میشود، هرچند عدد تأخیر صفر نوشته شده است.
تأخیر صفر به معنی اجرای فوری یا زمان دقیق صفر میلیثانیه نیست. ترتیب کارهای آماده و مشغولبودن مسیر اجرای فعلی بر زمان واقعی اثر میگذارد. افزودن async هم یک محاسبهٔ سنگین همگام را خودکار به کار پسزمینه تبدیل نمیکند. این مدخل نقشهٔ اولیهٔ انتظار را میدهد؛ برای مدیریت نتیجه و خطا، مدخلهای Promise و async/await را بخوانید. برای تمرین، پیش از جابهجایی خطها ترتیب خروجی را بنویسید و سپس اجرا کنید.
کجا به کار میآید؟
- فهمیدن علت آمادهنبودن نتیجهٔ شبکه در خط بعدی
- تشخیص تفاوت callback فوری با کاری که برای بعد زمانبندی شده است
از تعریف تا یک مثال واقعی
function runNow(done) {
done('همگام');
}
console.log('شروع');
runNow((message) => console.log(message));
setTimeout(() => console.log('بعدتر'), 0);
console.log('پایان');
شروع همگام پایان بعدتر
این مثال چطور کار میکند؟
شروع در مسیر همگام چاپ میشود.
runNow callback را فوری اجرا میکند و پیام همگام دیده میشود.
setTimeout فقط کار بعدی را ثبت میکند؛ ابتدا پایان و سپس بعدتر چاپ میشود.
اشتباه رایج
هر callback ناهمگام نیست. همچنین setTimeout با صفر، callback را وسط کد همگام جاری اجرا نمیکند و زمان دقیق اجرا را تضمین نمیکند.
این را به خاطر بسپارید
زمان آغاز کار و زمان دریافت نتیجه را جدا ببینید؛ قرارداد ابزار تعیین میکند callback چه زمانی اجرا شود.