ساختن یک سیستم واکنشی در TypeScript – مقدمه ای بر واکنش پذیری

اخیراً ، من خواندم نوشتن مترجم در GO، یک کتاب عالی که شما را از طریق ساخت زبان برنامه نویسی میمون قدم به قدم می گذارد. از آنجا که من با Go آشنا نبودم ، تصمیم گرفتم به جای آن ، مترجم را در TypeScript پیاده سازی کنم ، ابتدا رویکرد شی گرا مورد استفاده در کتاب را دنبال کردم ، اما بعد از اتمام ، آن را با استفاده از یک سبک کاربردی تر به روز کردم. من از ژنراتورها برای رسیدگی به وضعیت استفاده کردم لکسر و جریان نشانه ها در تجزیه کنندهبشر من مجبور به به روزرسانی آن نبودم ارزیاب، زیرا همیشه مجموعه ای از کارکردها بود.
در حالی که من از نتیجه خوشحال شدم ، زیرا من آن را به یک رویکرد کاربردی تر منتقل کرده بودم ، اما هنوز متغیرهای قابل تغییر است. من دوست داشتم چگونه در ارزیاب من هیچ متغیر “جهانی” نداشتم ، اما لازم بود که تجزیه کننده را پخش کنم ، و باید قبل از حرکت نیز بتوانم به آن جریان نگاه کنم.
این باعث شد من به نحوه برخورد با آن بپردازم مدیریت دولت به روشی که از جهش مستقیم جلوگیری می کند.
برنامه نویسی عملکردی و مدیریت دولت
وقتی با ایالات کار می کنیم ، اغلب با یک چالش مشترک روبرو می شویم: جهش پذیری. در یک الگوی ضروری ، ایالت ها با گذشت زمان تغییر می کنند و منجر به عوارض جانبی ، اشکال زدایی سخت تر و افزایش پیچیدگی می شوند.
اینجاست برنامه نویسی عملکردی (FP) یک رویکرد قابل پیش بینی تر و ایمن تر را ارائه می دهد. در FP ، عملکردهای خالص یک مفهوم اساسی است. یک تابع است خالص اگر دو شرط را برآورده کند:
- عوارض جانبی ندارد: این هیچ متغیر خارجی را اصلاح نمی کند یا عملیاتی مانند تغییر اشیاء جهانی ، نوشتن روی یک پرونده یا دستکاری DOM را انجام نمی دهد.
- خروجی قطعی: با توجه به ورودی های یکسان ، همیشه همان خروجی را برمی گرداند.
بیایید این را با یک مثال تجزیه کنیم. تصور کنید که می خواهیم دو شماره اضافه کنیم ، بوها وت شرحبشر با برنامه نویسی ضروری ، شما کاری مانند:
const a = 2;
const b = 3;
console.log(a + b);
اما ، می توانید به جای آن با استفاده از یک عملکرد خالص این کار را انجام دهید:
const add = (a: number, b: number): number => a + b;
console.log(add(2, 3)); // Always returns 5
با این حال ، تفاوت بین این و یک تابع ناخالص مشخص است وقتی برخی از متغیرها جهانی و قابل تغییر هستند.
let total = 0;
const addToTotal = (value: number) => {
total += value; // Modifies an external variable
return total;
};
console.log(addToTotal(3)); // Returns 3
console.log(addToTotal(3)); // Returns 6 (different output for the same input)
اکنون ، هر بار که تماس می گیریم addToTotal
ما در حال افزایش هستیم total
متغیر ، به روشی که قابل پیش بینی نباشد. به این یک اثر جانبی گفته می شود.
این رویکرد هنگامی که چندین قسمت از کد به همان حالت بستگی داشته باشد مشکل ساز می شود و می تواند بدون محدودیت آن را اصلاح کند و منجر به آن شود شرایط مسابقه یا اشکالات سخت را دوباره تولید کنید.
حالت تغییر ناپذیر و برنامه نویسی عملکردی
برای جلوگیری از این مشکلات ، برنامه نویسی عملکردی ساختار داده های تغییر ناپذیربشر به جای اصلاح وضعیت موجود ، ما نسخه جدیدی را با تغییرات کاربردی برمی گردانیم:
const state = { count: 0 };
const incrementState = (state: { count: number }) => {
return { ...state, count: state.count + 1 };
};
const newState = incrementState(state);
console.log(state.count); // 0
console.log(newState.count); // 1
این رویکرد چندین مزیت کلیدی را ارائه می دهد:
- قابلیت پیش بینی: از اجتناب از جهش ، تغییرات آسان تر است.
- اشکال زدایی ساده تر: اگر دولت به طور غیر منتظره ای تغییر نکند ، شناسایی اشکالات آسان تر و تولید مثل است.
- بهینه سازی با ساختارهای غیرقابل تغییر کارآمد: کتابخانه ها دوست دارند همیشه یا تکنیک هایی مانند اشتراک ساختاری به روزرسانی های کارآمد بدون کپی کردن کل ساختارهای داده اجازه دهید.
اگر نتوانیم دولت را مستقیماً به روز کنیم ، چگونه می توانیم یک کشور مشترک را حفظ کنیم که در تماس های عملکردی باقی بماند؟ پاسخ کوتاه این است: ما این کار را نمی کنیم، حداقل ، نه به معنای سنتی.
با این حال ، اگر با React کار کرده اید ، احتمالاً متوجه شده اید که اجزای کاربردی می توانند حالت را ذخیره و به روز کنند. اما چگونه؟ اگر توابع بدون تابعیت هستند ، آن کشور کجا زندگی می کند؟
این ما را به برنامه نویسی واکنشی، پارادایم ای که مدل ها را به طور اعلام کننده تغییر می دهد ، بدون تکیه بر جهش مستقیم.
برنامه نویسی واکنشی چیست؟
هنگامی که ما نیاز به به اشتراک گذاشتن حالت در یک برنامه داریم ، نگه داشتن آن در همگام سازی می تواند مشکل باشد. اگر چیزی می تواند آن را به روز کند ، چگونه می دانید چه چیزی تغییر می کند و چه زمانی؟ این جایی است که برنامه نویسی واکنشی وارد می شود. اعلانی پارادایم برای حل این مشکل. به جای اینکه داده ها را به عنوان مقادیر استاتیک که به صورت دستی به روز می کنیم ، درمان کنیم ، آن را به عنوان یک مدل می کنیم جریان به روزرسانی ها، اطمینان از مدیریت دولت قابل پیش بینی در سراسر برنامه.
در هسته آن ، الف سیستم واکنشی به ما اجازه می دهد تا روابط بین قطعات مختلف داده را تعریف کنیم ، به طوری که وقتی یک مقدار تغییر می کند ، هر آنچه که به آن بستگی دارد ، بر این اساس به روز می شود ، بدون اینکه نیاز به مداخله دستی صریح داشته باشد.
این الگوی به ویژه در طیف گسترده ای از سناریوها مانند:
- رابط های کاربر – به روزرسانی مؤلفه ها هنگام تغییر در داده ها ، از بازپرداخت مجدد غیر ضروری جلوگیری می کند.
- خط لوله های پردازش داده – داده های جریان را به صورت واکنشی و فیلتر کردن.
- همگام سازی حالت – نگه داشتن سیستم های توزیع شده در همگام سازی بدون نظرسنجی.
- توسعه بازی – مدیریت وضعیت بازی ، شبیه سازی فیزیک یا رفتارهای هوش مصنوعی.
- سیستم های اتوماسیون و رویداد محور – تحریک گردش کار به صورت پویا بر اساس تغییرات در داده ها.
برخلاف برنامه نویسی ضروری برنامه نویسی واکنشی به ما اجازه می دهد تا هنگام تغییر داده ها چه اتفاقی بیفتد و به سیستم اجازه دهیم که به روزرسانی ها را به طور کارآمد انجام دهد.
چگونه واکنش پذیری با برنامه نویسی عملکردی تراز می شود
اگر بررسی کنیم که چه چیزی یک سیستم واکنشی را واقعاً مؤثر می کند ، بسیار شبیه به آنچه از توابع خالص و FP نیاز داریم. اول ، شما می خواهید از جهش مستقیم حالت جلوگیری کنید. دوم ، ترکیب عملکرد ، ایجاد رفتارهای قابل پیش بینی را آسان تر می کند. و سرانجام ، باید عوارض جانبی با دقت مدیریت شود.
این جایی است که مفاهیم مانند نشانبا مقادیر محاسبه شدهوت اثرات واکنشی بیا بازی
ظهور سیگنال ها در جاوا اسکریپت مدرن
یکی از الگوهای بسیار اتخاذ شده در سیستم های واکنشی مدرن ، نشانهبشر بوها نشانه یک نوع خاص از متغیر واکنشی است که به طور خودکار وابستگی ها و به روزرسانی های آن را هر زمان که مقادیر متکی به تغییر باشد ، ردیابی می کند. بر خلاف مدل های سنتی رویداد محور ، سیگنال ها یک ریز دانه و روش کارآمد برای انتشار تغییرات.
سیگنال ها به حدی محبوب شده اند که بسیاری از چارچوب ها ، مانند زاویه ای ، جامد ، svelte و peact ، پیاده سازی های خود را اتخاذ کرده اند. به همین دلیل ، مفهوم نشان اکنون برای استاندارد سازی در جاوا اسکریپت در نظر گرفته شده است. در TC39 کمیته ، مسئول در حال تحول جاوا اسکریپت ، یک پیشنهاد فعال برای معرفی سیگنال ها به عنوان یک ویژگی زبان داخلی دارد ، تا به همان چارچوب ها اجازه دهد تا هنگام استفاده از آنها از تجربه و عملکرد بهتری استفاده کنند.
این واقعیت که سیگنال ها در نظر گرفته می شوند حمایت بومی چقدر ضروری است مدیریت دولت واکنشی نه تنها در چارچوب های UI بلکه به طور کلی برنامه نویسی شده است.
چه می آید بعد؟
با وجود این بنیاد ، ما آماده هستیم تا چگونگی ساخت سیستم واکنش پذیر سبک از ابتدابشر در این سری ، ما به مکانیک های اصلی در پشت سیگنال ها و چگونگی اجرای آنها به صورت کارآمد در TypeScript شیرجه خواهیم شد.