Promise.all در جاوا اسکریپت – از صفر تا صد


Promise-ها در جاوا اسکریپت یکی از API-های قدرتمند هستند که به اجرای عملیات ناهمگام کمک میکنند. Promise.all عملیات ناهمگام را به سطح بالاتری ارتقا داده است و به گروهبندی promise-ها کمک کرده است. به بیان دیگر با استفاده از Promise.all در جاوا اسکریپت میتوان گروهی از عملیات «همزمان» (concurrent) را اجرا کرد.
پیشنیاز مطالعه این مطلب آن است که با مفهوم Promise در جاوا اسکریپت آشنا باشید. اگر چنین نیست پیشنهاد میکنیم، مقاله «Promise در جاوا اسکریپت و کاربردهای آن — به زبان ساده» را مطالعه کنید.
Promise.all چیست؟
Promise.all در واقع یک promise است که ارائه از Promise-ها را به عنوان ورودی (عنصر تکرارپذیر = iterable) میگیرد. سپس وقتی که همه promise-ها پاسخ داده شوند یا هر یک از آنها رد شوند، Promise.all نیز به پایان میرسد.
برای نمونه فرض کنید 10 Promise دارید که عملیات ناهمگامی برای یک فراخوانی شبکه یا اتصال پایگاه داده اجرا میکنند. لازم است که بدانید همه Promise-ها چه زمانی پاسخ داده میشوند و یا لازم است صبر کنید تا همه آنها به پایان برسند. بدین ترتیب همه آنها را به Promise.all میفرستید و سپس Promise.all خودش به عنوان یک Promise زمانی که هر 10 Promise پاسخ داده شوند و یا هر یک از آنها رد شوند، به پایان میرسد.
به کد زیر توجه کنید:
همان طور که میبینید، ما یک ارائه را به Promise.all ارسال کردهایم و زمانی که هر سه Promise پاسخ داده شوند، Promise.all نیز پایان مییابد و خروجی در کنسول ارائه میشود.
به مثال زیر نیز توجه کنید:
در مثال فوق، Promise.all در طی 2000 میلیثانیه پس از این که خروجی به صورت یک ارائه در کنسول ارائه شود پایان مییابد.
ترتیب Promise-ها
یک نکته جالب در مورد Promise.all این است که ترتیب Promise-ها در آن حفظ میشود. نخستین Promise در ارائه به عنوان نخستین عنصر ارائه خروجی ارائه میشود، Promise دوم عنصر دوم ارائه است و همین طور تا آخر.
به مثال زیر نیز توجه کنید:
همان طور که میبینید اگر یکی از Promise-ها رد شود، همه موارد باقیمانده Promise-ها نیز شکست میخورند. در این صورت Promise.all نیز رد خواهد شد.
در برخی موارد ما به چنین موقعیتی نیاز نداریم. در واقع در این موارد لازم است که همه Promise-ها صرف نظر از این که یکی از آنها رد شود یا نه اجرا شوند و احتمالاً مورد رد شده را نیز در ادامه میتوان مدیریت کرد. مدیریت این وضعیت به صورت زیر ممکن است:
کاربردهای Promise.all
فرض کنید لازم است تعداد زیادی عملیات ناهمگام مانند ارسال انبوه ایمیلهای بازاریابی به هزاران کاربر را انجام دهید.
شبه کد ساده آن چنین میتواند باشد:
مثال فوق سرراست است. اما چندان کارآمد نیست. در نقطهای از زمان، پشته بسیار سنگین میشود و جاوا اسکریپت با انبوهی از درخواستهای باز اتصال HTTP مواجه خواهد بود که میتوانند سرور را کار بیندازند.
یک رویکرد ساده و کارآمد میتواند این باشد که این کار در دستهبندیهای مختلف انجام یابد. 500 کاربرِ نخست انتخاب و ایمیلها ارسال میشوند و صبر میکنیم تا همه اتصالهای HTTP بسته شوند. سپس دسته بعدی را پردازش میکنیم و همین طور تا آخر. مثال زیر را در نظر بگیرید:
سناریوی دیگری را در نظر بگیرید. فرض کنید لازم است یک API بسازیم که اطلاعاتی را از API-های شخص ثالث میگیرد و همه پاسخها را از آن API-ها تجمیع میکند.
در این حالت Promise.all بهترین روش برای انجام این کار است. چگونگی آن را در کد زیر ملاحظه میکنید:
سخن پایانی
در پایان باید اشاره کنیم که Promise.all بهترین روش برای تجمیع یک گروه از Promise-ها در یک Promise منفرد است. این یکی از بهترین روشها برای رسیدن به «همزمانی» (Concurrency) در جاوا اسکریپت است. امیدواریم از مطالعه این نوشته بهره برده باشید.
اگر این مطلب برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای جاوا اسکریپت
- آموزش JavaScript ES6 (جاوا اسکریپت)
- مجموعه آموزشهای برنامهنویسی
- Promise در جاوا اسکریپت و کاربردهای آن — به زبان ساده
- آموزش جاوا اسکریپت مقدماتی: ساخت بازی حدس اعداد — به زبان ساده
==