ali.bayat
ali.bayat
خواندن ۳ دقیقه·۳ سال پیش

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

استفاده از پرامس ها در 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 از طریق کامپوزر:

نصب ReactPHP
نصب ReactPHP

حالا باید یک پرامس بسازیم:

ساخت یک پرامس
ساخت یک پرامس

درست مانند جاوا اسکریپت ، ما یک آبجکت Promise داریم که دو کلوژر را می پذیرد:

کلوژر resolver و کلوژر canceller .. با مقدار دهی این کلوژر ها کد ما شبیه زیر می‌شود:

پرامس ها در ReactPHP
پرامس ها در ReactPHP

همانطور که می‌بینید resolver سه پارامتر را می‌پذیرد:

  • پارامتر resolve : زمانی فراخوانی می‌شود که نتیجه پرامس موفقیت آمیز و همراه با نتیجه باشد.
  • پارامتر reject : زمانی فراخوانی می‌شود که می‌خواهید در صورت بروز هرگونه خطا یا اکسپشن، پرامس را reject کنید.
  • پارامتر notify : زمانی فراخوانی می‌شود که می‌خواهید اطلاعاتی درباره پیشرفت یک پرامس داشته باشید.

اگر اکسپشنی در resolver یا canceller رخ دهد پرامس ریجکت می‌شود. همچنین کلوژر resolver بلا فاصله اجرا می‌شود اما کلوژر canceller تنها پس از فراخوانی متد cancel توسط consumer ها اجرا می‌شود..



با تمام مواردی که گفته شد به بخش پایانی این مطلب میرسیم.. استفاده از پرامسی که ساختیم.. در اینجا هم درست مانند جاوا اسکریپت به یک متد then دسترسی داریم:

پرامس ها در ReactPHP
پرامس ها در ReactPHP

کلوژر اول در صورت پایان کار موفق پرامس و کلوژر دوم در صورت ریجکت شدن پرامس، اجرا می‌شوند. همچنین میتوانید پرامس ها را chain کنید:

پرامس ها در ReactPHP
پرامس ها در ReactPHP


اجرای کد ها به صورت asynchronous در PHP نوید انجام کارهایی را می‌دهد، که پیش از این ممکن نبود.. از پیاده سازی وب‌سرور، ‌سوکت سرور و سوکت کلاینت گرفته تا پیاده سازی Async DNS resolver و UDP Client و غیره... آن هم تنها با استفاده از PHP

برای بررسی بیشتر کتابخانه ReactPHP می‌توانید از وب سایت آن دیدن کنید.

asynchronousphp
توسعه دهنده ارشد وب
شاید از این پست‌ها خوشتان بیاید