از روزی که به شرکت بله و تیم شهریار پیوستم متوجه شدم که یکی از ابزارهایی که باید کار کنم RXJS هست و به نوعی باید Reactive کد بزنم! از اونجایی که من عاشق یادگیری چیزهای جدیدم و کنجکاوی خاصی دارم تا بتونم زیر و بم همه چیز رو در بیارم و در این مورد اتفاقا وسواس هم دارم خواستم اول بدونم Reactive کد زدن یعنی چی؟
اما بعد از سرچ های متوالی و گشت و گذار در سایت های مختلف متوجه شدم که این مفهوم رو خیلی سخت توضیح دادن و یا حداقل برای من درک کردنش یکم سخت بود برای همین تصمیم گرفتم این مطلب رو بنویسم و خیلی کوتاه و ساده در مورد Reactive Programming صحبت کنم.
مفهوم Reactive Programming به معنای کدنویسی کردن توسط استریم هایی از داده ها به صورت ناهمزمان هست.
جمله ی بالا احتمالا دارای عباراتی هست که برای اولین بار می خونید مثل : " استریم هایی از داده ها "
شاید الان بگید این چه تعریف ساده ای بود دیگه بدتر گیجمون کردی ?
خب پس برمیگردیم یکم عقب تر تا ابتدا با معماری message-driven آشنا بشیم اون موقع احتمالا فهمیدن جمله ی بالا خیلی ساده تر و راحت تر از الان بشه !
همه ی کارهایی که توی این دنیا انجام میدیم async هست !
بیاید با یک مثال ادامه بدیم :
فرض میکنیم شما میخواید قهوه خامه ای درست کنید. اما متوجه میشید که خامه و شکر ندارین.
اینجا 2 تا سناریو پیش رو داریم !
سناریوی اول:
شما زیر کتری رو روشن می کنید و تا وقتی که قهوه داره دم می کشه سری به سوپرمارکت محل می زنید و خامه و شکر می خرید ، وقتی برگردید قهوه هم دم کشیده و خامه و شکر رو بهش اضافه می کنید و نوش جان می کنید و از زندگی لذت می برید ☕️
سناریوی دوم:
ابتدا به سوپرمارکت میرید و بعد از خرید خامه و شکر به خونه برمیگردید و تازه قهوه رو دم می کنید و هنگامی که زل زدید به کتری همزمان به بدهی هاتون فکر میکنید تا قهوه حاضر بشه و در آخر اگه از افسردگی جان سالم به در ببرید می تونید یه قهوه بخورید ?
همونطوری که در دو سناریوی بالا دیدید معماری message-driven شما رو از مکان و زمان جدا می کنه!
یک مرز async براتون ایجاد میکنه و می تونه event-driven باشه و یا actor-base (در مقاله های بعدی مفصل بهشون می پردازیم اما فقط بدونید در مدل event-driven ، این event های تولید شده تبدیل به یک جریان داده ی بی انتها میشن ( یعنی عمل streaming اتفاق میوفته ) و سرویس های نرم افزاری در راستای این جریان اطلاعات اقدام به Validation , Enrichment, Filtering, Processing … و حتی تولید رویداد های جدید می کنند.)
حالا وقتشه برگردیم و یک بار دیگه این بیسیک ترین تعریف reactive programming رو بخونیم :
Reactive programming is programming with asynchronous data streams.
توی این جمله احتمالا مبهم ترین قسمت همون data stream باشه ? ( خب طبیعتا داخل data stream هم دوباره مبهم ترین قسمت خود stream باشه ) !
احتمالا اگر قبلا در مورد stream جست و جو کرده باشید به رایج ترین تعریف اون یعنی جمله ی زیر رسیدید:
A stream is a sequence of ongoing events (state changes) ordered in time.
یک محور زمان در نظر بگیرید. به مجموعه event ها ( اتفاقاتی که منجر به تغییر وضعیت میشن ) یِ متوالی و پشت سر هم میگن stream !
اگه بخوام صرفا یه تصور ذهنی براتون ایجاد کنم می تونم بگم زندگی هر آدم از لحظه ی تولدش تا مرگ (complete ) بر محور زمان یک جور stream به حساب میاد !
حالا بریم وارد دنیای برنامه نویسی بشیم و چند تا مثال واقعی تر هم از stream باهم ببینیم ?
// a number that goes up by 1 every second [0,1,2,3,4] // a sequence of x and y positions of mouse click events [(12,34), (345,22), (1,993)] // a json representation of the whole form as the user enters data [ { "name": "A" }, { "name": "As" }, { "name": "Asi" }, { "name": "Asim" } ]
هر کدوم از این مثال هایی که زدم می تونن یه stream باشن ! در واقع stream هر چیزی می تونه باشه ! ?
یعنی ما می تونیم stream ای از دیتا ، از کلیک موس ، از Network Request و ... داشته باشیم.
ایده ی اصلی Reactive Programming پیرامون ساختن stream های متنوع و کنترل کردن اون ها توسط operation های متفاوت می چرخه ( حالا تعریف بهتر و ملموس تری شد نه؟?)
این operation ها اغلب توابع pure functional ای هستند که توسط ابزارهایی برای Reactive کد زدن در اختیار شما قرار داده میشه!
خب حالا که فهمیدیم Reactive Programming یعنی چی سوال مهم بعدی پیش میاد ❓
خب اگه شما اولین باره که reactive programming به چشمتون میخوره باید بگم که احتمالا تا قبل از این فقط Imperative کد می زدین ( یعنی همون شکل سنتی و دستوری سابق )
حالا اگه میخواید پارادایم های برنامه نویسی رو بهتر بشناسید توصیه میکنم این لینک ? رو بخونید!
خب برگردیم سر بحث اصلیمون ! چطوری وقتی تا حالا Imperative کد می زنیم ذهنیتمون رو تغییر بدیم و Reactive کد بزنیم؟
با یک مثال شروع می کنیم ?
تابع add رو در نظر بگیرید.
مقدار c مستقیما به مجموع مقادیر A و B مربوطه ! و اگر این بین B تغییر کنه دوتا اتفاق پیش میاد :
1- ما باید بفهمیم که B تغییر کرده !
2- ما باید بفهمیم که تغییر کردنِ B روی تغییر کردنِ C هم تاثیر گذاره !
خب در دنیای وب اپلیکیشن های امروزی این کار خیلی رایجه که دیتاها توسط کاربران به صورت لحظه ای و مداوم تغییر کنند. از طرفی اگر بخوایم به صورت Imperative متوجه این تغییر کردن ها بشیم به callback-hell می رسیم ? ( که خب این پروژه رو پیچیده و به مرور از دسترس خارج می کنه )
خب ما در reactive programming قراره به همه چیز به چشم stream نگاه کنیم.
پس A و B و C دیگه یک value نیستن بلکه یک stream محسوب میشن ?
اینجا فانکشن add دقیقا همون operation مد نظر ماست که ارتباط و کنترل A , B و C رو به عهده میگیره!
خب مفتخرم شما رو با شغل جدیدتون آشنا کنم ! شما لوله کش هستید ?
این stream ها حکم لوله هایی رو دارند که شما تصمیم میگیرید کی و کجا بهم وصل بشن و نتیجه رو که همون آب باشه کجا و چجوری مشاهده کنیم ( تا بحث لوله کشی داغه بگم که شما همونطور که می تونید هم لوله ی آب داشته باشید هم تصفیه ی آب، اینجا هم می تونید چندین operation برای کنترل stream هاتون داشته باشید)
خب حالا دیگه خیلی راحته و هر زمان که این stream ها آپدیت بشن نتیجه رو به صورت خودکار خواهیم دید ?
هر کسی که Reactive کد زد نمی تونه ادعا کنه که داره یک سیستم Reactive رو توسعه میده !
این دو مفهوم باهم تفاوت زیادی دارند از جمله اینکه در یک سیستم Reactive ما پیرامون 4 تا مفهوم میچرخیم :
که در مقاله ی بعدی مشخصه های یک سیستم Reactive رو با مثال و مرور تاریخ حوادث دنیای نرم افزار ادامه میدیم.
امیدوارم از مقاله لذت برده باشید. سعی کردم کوتاه و مفید توضیح بدم! متاسفانه پیرامون این مطلب توضیحاتی در وب فارسی نیست و در وب انگلیسی هم اکثرا سیستماتیک بودن یک Reactive Application رو بررسی کردند و با تعاریف سخت باعث شدن که این توهم بوجود بیاد Reactive Programming یک مفهوم سخت و غیرقابل فهمه در حالی که اینطوری نیست ?
اگه سوالی داشتید در نظر ها بپرسید جواب میدم ?
دوست دارید ویدیوهای آموزشی Reactive Programming رو با آموزش RXJS استارت بزنیم؟ ?
راه های ارتباطی با من :