جاوا اسکریپت طیف وسیعی از توابع و روشهای قدرتمند را برای کار با آرایهها ارائه میدهد، از جمله متد forEach که به طور گسترده استفاده میشود. با این حال اگر شما تا به حال سعی کرده اید از کلمه کلیدی await در یک حلقه forEach برای مدیریت عملیات ناهمزمان استفاده کنید، ممکن است با رفتار غیرمنتظره ای و عجیبی مواجه شده باشید.در این مقاله، بررسی میکنیم که چرا forEach از await پشتیبانی نمیکند و روش صحیح اجرای عملیات async را در یک حلقه forEach در جاوا اسکریپت میآموزیم.
درک forEach و اجرای Synchronous:
متد forEach در جاوا اسکریپت روشی ساده و مختصر برای تکرار روی عناصر یک آرایه است.تابع callback را به عنوان آرگومان می گیرد و آن را برای هر عنصر آرایه اجرا می کند.با این حال، توجه به این نکته مهم است که forEach به صورت Synchronous عمل می کند. این بدان معنی است که قبل از رفتن به تکرار بعدی منتظر نمی ماند تا عملیات async کامل شود.
چرا forEach از Await پشتیبانی نمی کند:
پشتیبانی نکردن از await در داخل حلقه forEach از این واقعیت ناشی می شود که forEach انتظار بازگشتی عملیات async از تابع callback را ندارد یا به آن رسیدگی نمی کند. کلمه کلیدی await فقط می تواند در یک تابع async استفاده شود که با کلمه کلیدی await در اعلان آن مشخص شده است. متد forEach که Synchronousاست، مکانیسمی برای توقف اجرا و منتظر ماندن برای حل شدن promises ارائه نمی دهدو در نتیجه، استفاده از await در یک حلقه forEach اثر مورد نظر را نخواهد داشت.
مثالی از مشکلات استفاده از Await داخل حلقه forEach :
- وقتی این کد را اجرا می کنیم با مشکل مواجه می شویم و حلقه forEach برای کلمه کلیدی await مکث نمی کند و عملیات async شروع می شود اما منتظر نمی ماند و در نتیجه، دستور لاگ «“All items processed”» قبل از تکمیل عملیات async اجرا میشود.این رفتار به این دلیل رخ می دهد که forEach منتظر حل شدن promises نمی ماند و باعث خروجی غیرمنتظره و نادرست می شود.
اجرای صحیح عملیات Async در forEach:
برای مدیریت صحیح عملیات async در یک حلقه forEach، باید از یک رویکرد کمی متفاوت استفاده کنیم. به جای استفاده از forEach، میتوانیم از حلقه for…of استفاده کنیم که به ما امکان میدهد با توابع ناهمزمان و کلمه کلیدی await کار کنیم.
یک مثالی با هم ببینیم:
ما یک تابع async processArray را تعریف می کنیم که با استفاده از حلقه for...of روی هر آیتم در آرایه تکرار می شود , ما منتظر اجرای یک تابع ناهمزمان asyncFunction هستیم که عملیات async مورد نیاز را روی هر مورد انجام می دهد و با استفاده از این رویکرد، اطمینان حاصل می کنیم که هر تکرار قبل از حرکت به عملیات بعدی منتظر تکمیل عملیات async است.
امیدوارم این مطالب کمی بهتون کمک کرده باشه:)
مهدیار جعفری