وارونگی کنترل در تماس های جاوا اسکریپت: چرا وعده ها جواب می دهند؟

تابع فراخوانی تابعی است که به عنوان آرگومان به تابع دیگری منتقل میشود، که سپس در داخل تابع خارجی برای تکمیل نوعی روال یا عمل فراخوانی میشود. به دو طریق می توان تماس را فراخوانی کرد: همزمان و ناهمزمان. این اساسی ترین الگوی همگام در جاوا اسکریپت است.
مثلا:
آ و ب اکنون تحت کنترل مستقیم برنامه اصلی JS اتفاق می افتد. اما C به تعویق افتاد تا بعداً اتفاق بیفتد، و تحت کنترل یک طرف دیگر، در این مورد، تابع ajax (..) است. در یک مفهوم اساسی، این نوع از دست دادن کنترل به طور منظم باعث ایجاد مشکلات زیادی برای برنامه ها نمی شود.
با این حال، نادر بودن برای نادیده گرفتن مشکل یا مشکل کافی نیست. در واقع، این یکی از مشکلات اصلی طراحی مبتنی بر تماس است. این حول این ایده می چرخد که گاهی اوقات ajax (..) یا “پارتی” که ادامه تماس خود را به آن ارسال می کنید تابعی نیست که شما نوشته اید یا مستقیماً آن را کنترل می کنید. اغلب اوقات این یک ابزار است که توسط شخص ثالث ارائه شده است.
ما به این می گوییم ” وارونگی کنترل “ زمانی که بخشی از برنامه خود را می گیرید و کنترل اجرای آن را به شخص ثالث دیگری واگذار می کنید. یک “قرارداد” ناگفته بین کد شما و ابزار شخص ثالث وجود دارد – مجموعه ای از چیزهایی که انتظار دارید حفظ شوند.
مشکل «وارونگی کنترل» چیست؟
یک مثال برای درک بهتر این مشکل وجود دارد.
فرض کنید در حال ساختن یک وب سایت رزرواسیون سفر برای شرکت خود هستید. شما یک دکمه “اکنون کتاب” را اضافه کرده اید که از تابع ()createBooking یک کتابخانه شخص ثالث استفاده می کند. این تابع رزرو را پردازش می کند و سپس با تماس با شما تماس می گیرد تا یک ایمیل تأیید برای مشتری ارسال کند.
این کد ممکن است به شکل زیر باشد:
همه چیز در طول تست کاملاً کار می کند. مردم شروع به رزرو بسته های مسافرتی در وب سایت شما می کنند و همه از کار شما راضی هستند. ناگهان، یک روز، شما از رئیس خود در مورد یک موضوع مهم تماس می گیرید. یک مشتری بسته ای را رزرو کرد و برای یک رزرو چهار ایمیل تأیید یکسان دریافت کرد.
شما شروع به رفع اشکال می کنید. شما بخشی از کد را که ایمیل تایید را ارسال می کند مرور می کنید و همه چیز درست به نظر می رسد. سپس بیشتر بررسی میکنید و متوجه میشوید که ابزار createBooking() از کتابخانه شخص ثالث، تابع callback شما را چهار بار فراخوانی کرده است که در نتیجه چهار ایمیل تأیید ارسال میشود.
شما با تیم پشتیبانی کتابخانه شخص ثالث تماس بگیرید و وضعیت را توضیح دهید. آنها به شما می گویند که قبلاً با این مشکل روبرو نشده اند، اما آن را اولویت بندی می کنند و به شما پاسخ می دهند. پس از یک روز، آنها با یافته های خود با شما تماس می گیرند. آنها دریافتند که یک قطعه کد آزمایشی، که قرار نبود فعال شود، باعث شده است که تابع ()createBooking چندین بار پاسخ تماس را فراخوانی کند.
موضوع از طرف آنها بود و به شما اطمینان دادند که رفع شده است. آنها بابت مشکل عذرخواهی کردند و تأیید کردند که این مشکل دوباره رخ نخواهد داد.
برای جلوگیری از هر گونه مشکل ناخواسته ای مانند آن پس از مدتی جستجو برای راه حل، یک عبارت if ساده مانند زیر را پیاده سازی می کنید که به نظر می رسد تیم از آن راضی است:
اما سپس یکی از مهندسان QA می پرسد، “اگر هرگز با تماس تماس نگیرند چه اتفاقی می افتد؟” اوه هیچ کدام از شما به این موضوع فکر نکرده بودید!
شما شروع به فکر کردن به همه چیزهای احتمالی می کنید که ممکن است با تماس آنها با شما اشتباه شود. در اینجا لیستی از برخی از مشکلات آمده است:
-
خیلی زود با تماس تماس بگیرید
-
تماس برگشتی خیلی دیر (یا هرگز)
-
تماس برگشتی خیلی کم یا خیلی زیاد (مانند مشکل در مثال بالا)
-
هر گونه خطا/استثنایی که ممکن است رخ دهد را ببلعید
-
…
احتمالاً متوجه خواهید شد که باید راهحلهای زیادی را برای موقعیتهای مختلف در کد خود پیادهسازی کنید، که کد را افتضاح و کثیف میکند، زیرا در هر تماس پاسخ داده شده به یک برنامه کاربردی لازم است.
وعده ها
اگر بتوانیم این وارونگی کنترل را وارونه کنیم چه؟ چه میشود اگر بهجای انتقال ادامه برنامه به طرف دیگری، انتظار داشته باشیم که این قابلیت را به ما بازگرداند تا بدانیم کارش چه زمانی تمام میشود، و سپس کد ما میتواند تصمیم بگیرد که چه کاری انجام دهیم؟
Promises یک راه قدرتمند برای مدیریت عملیات ناهمزمان در جاوا اسکریپت ارائه می دهد که به مسائلی مانند جهنم پاسخ به تماس و وارونگی کنترل رسیدگی می کند. برخلاف تماسهای برگشتی، Promises به شما امکان میدهد کارهای ناهمزمان را بدون از دست دادن کنترل کد خود مدیریت کنید.
سفارش یک چیزبرگر را در یک رستوران فست فود در نظر بگیرید. رسید دریافت میکنید، وعده چیزبرگر آیندهتان. در حالی که منتظر می مانید، می توانید کارهای دیگری انجام دهید و بدانید که در نهایت سفارش خود را دریافت خواهید کرد. به طور مشابه، یک Promise در جاوا اسکریپت یک مقدار آینده را نشان میدهد و به کد شما اجازه میدهد تا به راحتی پیش برود.
وعدهها نیز با ظرافت به شکستها رسیدگی میکنند، همانطور که ممکن است در صورت تمام شدن چیزبرگر در رستوران مطلع شوید. این ساختار کد شما را خواناتر و قابل نگهداری تر می کند.
من قصد ندارم در اینجا به طور عمیق به Promises بپردازم، اما با استفاده از آنها، می توانید کدهای ناهمزمان تمیزتر و قابل اطمینان تری بنویسید و کیفیت کلی برنامه های جاوا اسکریپت خود را بهبود بخشید.
برای مثال، برای وبسایت رزرو سفر که قبلاً توضیح دادیم، اگر ابزار شخص ثالث قولی را برگرداند، میتوانیم آن را به این صورت انجام دهیم:
هنگامی که یک Promise حل شد (با موفقیت تکمیل شد)، برای همیشه همینطور باقی می ماند – در آن نقطه به یک مقدار تغییر ناپذیر تبدیل می شود و سپس می توان آن را هر چند بار که لازم است مشاهده کرد. این بدان معناست که یک وعده حلشده، مقدار حلشده آن میتواند چندین بار در کد شما دسترسی داشته باشد یا از آن استفاده کند بدون اینکه بر وضعیت آن تأثیر بگذارد. این به شما امکان می دهد تا بدون نگرانی در مورد تغییر یا ارزیابی مجدد Promise، نتیجه عملیات ناهمزمان را در بخش های مختلف برنامه خود مدیریت کنید.
Promises راه حلی برای معکوس کردن مسائل کنترلی است که در کدهای فقط پاسخ به تماس رخ می دهد. برگشت به تماس نشان دهنده وارونگی کنترل است. بنابراین معکوس کردن الگوی تماس در واقع وارونگی وارونگی یا عدم وارونگی کنترل است. بازگرداندن کنترل به کد تماس که در وهله اول می خواستیم باشد.
منابع