اگر با جاوا اسکریپت آشنا باشید ، احتمالا با پرامس ها کار کردید یا حداقل درباره آنها شنیده اید. به طور خلاصه در جاوا اسکریپت یک پرامس (Promise) آبجکتی است که بین Producing Code و Consuming Code یک پیوند تشکیل میدهد.
اِستیت (وضعیت) هر آبجکت پرامس همواره یکی از ۳ گزینه زیر است:
برای ایجاد یک پرامس در جاوا اسکریپت به شکل زیر عمل میکنیم:
همانطور که میبینید، یک کلوژر به آبجکت Promise
پاس داده میشه، که ۲ آرگومان رو میپذیره; این ۲ آرگومان از سمت خود جاوا اسکریپت در اختیار ما قرار میگیرند
در سناریو های زیر، این ۲ کلوژر داخل آبجکت پرامس قابل فراخوانی هستند:
پس با در نظر گرفتن دو آرگومان resolve
و reject
پرامس ما شبیه به زیر میشود:
و برای استفاده از آن میتوان از متدهای then
، catch
، finally
استفاده کرد:
به پروسه بالا دقت کنید، ما داریم یک سری تسک رو فراخوانی میکنیم. و ممکنه یکی از این تسک ها زمان بر باشه. با استفاده از یک پرامس برای تسک زمان بر، ما داریم از ویژگی 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 از طریق کامپوزر:
حالا باید یک پرامس بسازیم:
درست مانند جاوا اسکریپت ، ما یک آبجکت Promise داریم که دو کلوژر را می پذیرد:
کلوژر resolver
و کلوژر canceller
.. با مقدار دهی این کلوژر ها کد ما شبیه زیر میشود:
همانطور که میبینید resolver
سه پارامتر را میپذیرد:
اگر اکسپشنی در resolver
یا canceller
رخ دهد پرامس ریجکت میشود. همچنین کلوژر resolver
بلا فاصله اجرا میشود اما کلوژر canceller
تنها پس از فراخوانی متد cancel
توسط consumer ها اجرا میشود..
با تمام مواردی که گفته شد به بخش پایانی این مطلب میرسیم.. استفاده از پرامسی که ساختیم.. در اینجا هم درست مانند جاوا اسکریپت به یک متد then
دسترسی داریم:
کلوژر اول در صورت پایان کار موفق پرامس و کلوژر دوم در صورت ریجکت شدن پرامس، اجرا میشوند. همچنین میتوانید پرامس ها را chain کنید:
اجرای کد ها به صورت asynchronous در PHP نوید انجام کارهایی را میدهد، که پیش از این ممکن نبود.. از پیاده سازی وبسرور، سوکت سرور و سوکت کلاینت گرفته تا پیاده سازی Async DNS resolver و UDP Client و غیره... آن هم تنها با استفاده از PHP
برای بررسی بیشتر کتابخانه ReactPHP میتوانید از وب سایت آن دیدن کنید.