استفاده از پرامس ها در PHP (به سبک جاوا اسکریپت)

استفاده از پرامس ها در PHP (به سبک جاوا اسکریپت)اگر با جاوا اسکریپت آشنا باشید ، احتمالا با پرامس ها کار کردید یا حداقل درباره آنها شنیده اید. به طور خلاصه در جاوا اسکریپت یک پرامس (Promise) آبجکتی است که بین Producing Code و Consuming Code یک پیوند تشکیل می‌دهد.کدی که اجرای آن ممکن است زمان‌بر باشد Producing codeو کدی که در انتظارِ نتیجهِ تسک زمان‌بر است، Consuming code خوانده می‌شوند.اِستیت (وضعیت) هر آبجکت پرامس همواره یکی از ۳ گزینه زیر است:استیت Pending یا در حال انتظاراستیت Fulfiled یا برآورده شدهاستیت Rejected یا رد شدهبرای ایجاد یک پرامس در جاوا اسکریپت به شکل زیر عمل می‌کنیم:پرامس در جاوا اسکریپتهمانطور که می‌بینید، یک کلوژر به آبجکت Promise پاس داده میشه، که ۲ آرگومان رو می‌پذیره; این ۲ آرگومان از سمت خود جاوا اسکریپت در اختیار ما قرار می‌گیرنددر سناریو های زیر، این ۲ کلوژر داخل آبجکت پرامس قابل فراخوانی هستند:پایان موفق تسک با یک valueریجکت شدن پرامس در صورت بروز خطا (با یک آبجکت error)پس با در نظر گرفتن دو آرگومان resolve و reject پرامس ما شبیه به زیر می‌شود:پرامس در جاوا اسکریپتو برای استفاده از آن می‌توان از متدهای then ، ‌catch ، finally استفاده کرد:پرامس در جاوا اسکریپتپرامس ها در PHPبه پروسه بالا دقت کنید، ما داریم یک سری تسک رو فراخوانی می‌کنیم. و ممکنه یکی از این تسک ها زمان بر باشه. با استفاده از یک پرامس برای تسک زمان بر، ما داریم از ویژگی non-Blocking IO بهره میبریم. یعنی اجرای کدهای بعد رو به اجرای اون تسک زمان‌بر وابسته نمی‌کنیم.. تسک زمان بر ما میتونه به صورت asynchronous و همزمان اجرا بشه. و یک پرامس در هر صورت (success/fail) نتیجه اون رو به ما اعلام میکنه.حالا اگر بخواهیم همین عملکرد رو در PHP داشته باشیم چی؟زبان PHP درست مثل جاوا اسکریپت single-thread هست. به این معنا که برای پردازش از یک call stack و یک memory heap بهره می‌برد. اما بر خلاف جاوااسکریپت در زبان PHP تا به اینجا (نسخه 8.0) پرامس ها تعبیه نشده اند. (هر چند که در PHP 8.1 قراره Fibers رو داشته باشیم)اینجاست که ReactPHP وارد محاسبات میشه. ReactPHP یک کتابخانه سطح پایین برای برنامه نویسی رویداد محور در PHP است; که در هسته اصلی آن یک حلقه رویداد (Event loop) وجود دارد که ابزارهای سطح پایین را ارائه می دهد. به شکل خلاصه این کتابخونه قطعه گمشده پازلی هست که اجرای کدها رو به صورت async در PHP ممکن میکنه.ممکنه این مفهوم برای اکثر توسعه دهنده های PHP ، مفهوم نسبتا جدیدی باشه، اما برای کسانی که با فریم‌ورک های NodeJs آشنا هستند، قطعه کد زیر بسیار منطقی و آشناست (با این تفاوت که در PHP اجرا میشه ?)نمونه کد ReactPHPاستفاده از پرامس های ReactPHPاستفاده از پرامس ها شامل ۲ مرحله کلی می‌شود .. ۱) ساخت یک پرامس و ۲) استفاده از آنابتدا برای نصب ReactPHP از طریق کامپوزر:نصب ReactPHPحالا باید یک پرامس بسازیم:ساخت یک پرامسدرست مانند جاوا اسکریپت ، ما یک آبجکت Promise داریم که دو کلوژر را می پذیرد:کلوژر resolver و کلوژر canceller .. با مقدار دهی این کلوژر ها کد ما شبیه زیر می‌شود:پرامس ها در ReactPHPهمانطور که می‌بینید resolver سه پارامتر را می‌پذیرد:پارامتر resolve : زمانی فراخوانی می‌شود که نتیجه پرامس موفقیت آمیز و همراه با نتیجه باشد.پارامتر reject : زمانی فراخوانی می‌شود که می‌خواهید در صورت بروز هرگونه خطا یا اکسپشن، پرامس را reject کنید.پارامتر notify : زمانی فراخوانی می‌شود که می‌خواهید اطلاعاتی درباره پیشرفت یک پرامس داشته باشید.اگر اکسپشنی در resolver یا canceller رخ دهد پرامس ریجکت می‌شود. همچنین کلوژر resolver بلا فاصله اجرا می‌شود اما کلوژر canceller تنها پس از فراخوانی متد cancel توسط consumer ها اجرا می‌شود..با تمام مواردی که گفته شد به بخش پایانی این مطلب میرسیم.. استفاده از پرامسی که ساختیم.. در اینجا هم درست مانند جاوا اسکریپت به یک متد then دسترسی داریم:پرامس ها در ReactPHPکلوژر اول در صورت پایان کار موفق پرامس و کلوژر دوم در صورت ریجکت شدن پرامس، اجرا می‌شوند. همچنین میتوانید پرامس ها را chain کنید:پرامس ها در ReactPHPاجرای کد ها به صورت asynchronous در PHP نوید انجام کارهایی را می‌دهد، که پیش از این ممکن نبود.. از پیاده سازی وب‌سرور، ‌سوکت سرور و سوکت کلاینت گرفته تا پیاده سازی Async DNS resolver و UDP Client و غیره... آن هم تنها با استفاده از PHPبرای بررسی بیشتر کتابخانه ReactPHP می‌توانید از وب سایت آن دیدن کنید.