RxJS ഉപയോഗിച്ച് ജാവാസ്ക്രിപ്റ്റിൽ റിയാക്ടീവ് പ്രോഗ്രാമിംഗ് കണ്ടെത്തുക. പ്രതികരണശേഷിയുള്ളതും വികസിപ്പിക്കാവുന്നതുമായ ആപ്ലിക്കേഷനുകൾ നിർമ്മിക്കുന്നതിനായി ഒബ്സെർവബിൾ സ്ട്രീമുകൾ, പാറ്റേണുകൾ, പ്രായോഗിക ആപ്ലിക്കേഷനുകൾ എന്നിവ പഠിക്കുക.
ജാവാസ്ക്രിപ്റ്റ് റിയാക്ടീവ് പ്രോഗ്രാമിംഗ്: RxJS പാറ്റേണുകളും ഒബ്സെർവബിൾ സ്ട്രീമുകളും
ആധുനിക വെബ് ഡെവലപ്മെന്റിന്റെ എപ്പോഴും വികസിച്ചുകൊണ്ടിരിക്കുന്ന ലോകത്ത്, പ്രതികരണശേഷിയുള്ളതും, വികസിപ്പിക്കാവുന്നതും, പരിപാലിക്കാൻ എളുപ്പമുള്ളതുമായ ആപ്ലിക്കേഷനുകൾ നിർമ്മിക്കേണ്ടത് അത്യാവശ്യമാണ്. അസിൻക്രണസ് ഡാറ്റാ സ്ട്രീമുകൾ കൈകാര്യം ചെയ്യുന്നതിനും നിങ്ങളുടെ ആപ്ലിക്കേഷനിലുടനീളം മാറ്റങ്ങൾ പ്രചരിപ്പിക്കുന്നതിനും റിയാക്ടീവ് പ്രോഗ്രാമിംഗ് (RP) ഒരു ശക്തമായ മാതൃക നൽകുന്നു. ജാവാസ്ക്രിപ്റ്റിൽ RP നടപ്പിലാക്കുന്നതിനുള്ള ജനപ്രിയ ലൈബ്രറികളിൽ, RxJS (റിയാക്ടീവ് എക്സ്റ്റൻഷൻസ് ഫോർ ജാവാസ്ക്രിപ്റ്റ്) ഒരു കരുത്തുറ്റതും വൈവിധ്യമാർന്നതുമായ ടൂൾ ആയി വേറിട്ടുനിൽക്കുന്നു.
റിയാക്ടീവ് പ്രോഗ്രാമിംഗ് എന്താണ്?
അതിൻ്റെ കാതൽ, റിയാക്ടീവ് പ്രോഗ്രാമിംഗ് എന്നത് അസിൻക്രണസ് ഡാറ്റാ സ്ട്രീമുകളും മാറ്റങ്ങളുടെ വ്യാപനവും കൈകാര്യം ചെയ്യുന്നതിനെക്കുറിച്ചാണ്. ഒരു സെൽ അപ്ഡേറ്റ് ചെയ്യുമ്പോൾ ബന്ധപ്പെട്ട ഫോർമുലകൾ സ്വയമേവ പുനഃക്രമീകരിക്കുന്ന ഒരു സ്പ്രെഡ്ഷീറ്റ് സങ്കൽപ്പിക്കുക. അതാണ് RP-യുടെ സത്ത - ഡാറ്റാ മാറ്റങ്ങളോട് ഡിക്ലറേറ്റീവും കാര്യക്ഷമവുമായ രീതിയിൽ പ്രതികരിക്കുക.
പരമ്പരാഗത ഇംപറേറ്റീവ് പ്രോഗ്രാമിംഗിൽ പലപ്പോഴും സ്റ്റേറ്റ് മാനേജ് ചെയ്യുകയും ഇവന്റുകൾക്ക് പ്രതികരണമായി ഘടകങ്ങൾ നേരിട്ട് അപ്ഡേറ്റ് ചെയ്യുകയും ചെയ്യുന്നു. ഇത് സങ്കീർണ്ണവും പിശകുകൾക്ക് സാധ്യതയുള്ളതുമായ കോഡിലേക്ക് നയിച്ചേക്കാം, പ്രത്യേകിച്ചും നെറ്റ്വർക്ക് അഭ്യർത്ഥനകൾ അല്ലെങ്കിൽ ഉപയോക്തൃ ഇടപെടലുകൾ പോലുള്ള അസിൻക്രണസ് പ്രവർത്തനങ്ങൾ കൈകാര്യം ചെയ്യുമ്പോൾ. RP ഇതിനെ ലളിതമാക്കുന്നത്, എല്ലാത്തിനെയും ഒരു ഡാറ്റാ സ്ട്രീം ആയി കണക്കാക്കുകയും ഈ സ്ട്രീമുകളെ രൂപാന്തരപ്പെടുത്താനും, ഫിൽട്ടർ ചെയ്യാനും, സംയോജിപ്പിക്കാനും ഓപ്പറേറ്ററുകൾ നൽകുകയും ചെയ്തുകൊണ്ടാണ്.
RxJS-നെ പരിചയപ്പെടുത്തുന്നു: ജാവാസ്ക്രിപ്റ്റിനായുള്ള റിയാക്ടീവ് എക്സ്റ്റൻഷൻസ്
ഒബ്സെർവബിൾ സീക്വൻസുകൾ ഉപയോഗിച്ച് അസിൻക്രണസ്, ഇവന്റ്-ബേസ്ഡ് പ്രോഗ്രാമുകൾ രചിക്കുന്നതിനുള്ള ഒരു ലൈബ്രറിയാണ് RxJS. ഡാറ്റാ സ്ട്രീമുകൾ എളുപ്പത്തിൽ കൈകാര്യം ചെയ്യാൻ നിങ്ങളെ അനുവദിക്കുന്ന ഒരു കൂട്ടം ശക്തമായ ഓപ്പറേറ്ററുകൾ ഇത് നൽകുന്നു. ഇവന്റുകളുടെയോ ഡാറ്റയുടെയോ സീക്വൻസുകൾ കാര്യക്ഷമമായി കൈകാര്യം ചെയ്യുന്നതിന് RxJS ഒബ്സെർവർ പാറ്റേൺ, ഇറ്ററേറ്റർ പാറ്റേൺ, ഫംഗ്ഷണൽ പ്രോഗ്രാമിംഗ് ആശയങ്ങൾ എന്നിവയെ അടിസ്ഥാനമാക്കിയുള്ളതാണ്.
RxJS-ലെ പ്രധാന ആശയങ്ങൾ:
- ഒബ്സെർവബിൾസ് (Observables): ഒന്നോ അതിലധികമോ ഒബ്സെർവർമാർക്ക് നിരീക്ഷിക്കാൻ കഴിയുന്ന ഒരു ഡാറ്റാ സ്ട്രീമിനെ പ്രതിനിധീകരിക്കുന്നു. അവ ലേസി (lazy) ആണ്, സബ്സ്ക്രൈബ് ചെയ്യുമ്പോൾ മാത്രമേ മൂല്യങ്ങൾ പുറത്തുവിടാൻ തുടങ്ങുകയുള്ളൂ.
- ഒബ്സെർവേഴ്സ് (Observers): ഒബ്സെർവബിൾസ് പുറത്തുവിടുന്ന ഡാറ്റ ഉപയോഗിക്കുന്നു. അവയ്ക്ക് മൂന്ന് രീതികളുണ്ട്: മൂല്യങ്ങൾ സ്വീകരിക്കുന്നതിന്
next()
, പിശകുകൾ കൈകാര്യം ചെയ്യുന്നതിന്error()
, സ്ട്രീമിന്റെ അവസാനം സൂചിപ്പിക്കുന്നതിന്complete()
. - ഓപ്പറേറ്റേഴ്സ് (Operators): ഒബ്സെർവബിൾസിനെ രൂപാന്തരപ്പെടുത്തുകയോ, ഫിൽട്ടർ ചെയ്യുകയോ, സംയോജിപ്പിക്കുകയോ, അല്ലെങ്കിൽ കൈകാര്യം ചെയ്യുകയോ ചെയ്യുന്ന ഫംഗ്ഷനുകൾ. വിവിധ ആവശ്യങ്ങൾക്കായി RxJS വിപുലമായ ഓപ്പറേറ്ററുകൾ നൽകുന്നു.
- സബ്ജക്ട്സ് (Subjects): ഒബ്സെർവബിൾസായും ഒബ്സെർവേഴ്സായും പ്രവർത്തിക്കുന്നു, ഇത് ഒന്നിലധികം സബ്സ്ക്രൈബർമാർക്ക് ഡാറ്റ മൾട്ടികാസ്റ്റ് ചെയ്യാനും സ്ട്രീമിലേക്ക് ഡാറ്റ പുഷ് ചെയ്യാനും നിങ്ങളെ അനുവദിക്കുന്നു.
- ഷെഡ്യൂളറുകൾ (Schedulers): ഒബ്സെർവബിൾസിന്റെ കൺകറൻസി നിയന്ത്രിക്കുന്നു, ഇത് കോഡ് സിൻക്രണസ് ആയോ അസിൻക്രണസ് ആയോ, വ്യത്യസ്ത ത്രെഡുകളിലോ, അല്ലെങ്കിൽ നിർദ്ദിഷ്ട കാലതാമസത്തോടെയോ എക്സിക്യൂട്ട് ചെയ്യാൻ നിങ്ങളെ അനുവദിക്കുന്നു.
ഒബ്സെർവബിൾ സ്ട്രീമുകൾ വിശദമായി
RxJS-ന്റെ അടിസ്ഥാനം ഒബ്സെർവബിൾസ് ആണ്. കാലക്രമേണ നിരീക്ഷിക്കാൻ കഴിയുന്ന ഒരു ഡാറ്റാ സ്ട്രീമിനെ അവ പ്രതിനിധീകരിക്കുന്നു. ഒരു ഒബ്സെർവബിൾ അതിന്റെ സബ്സ്ക്രൈബർമാർക്ക് മൂല്യങ്ങൾ പുറപ്പെടുവിക്കുന്നു, അവർക്ക് ആ മൂല്യങ്ങൾ പ്രോസസ്സ് ചെയ്യാനോ പ്രതികരിക്കാനോ കഴിയും. ഒരു ഉറവിടത്തിൽ നിന്ന് ഒന്നോ അതിലധികമോ ഉപഭോക്താക്കളിലേക്ക് ഡാറ്റ ഒഴുകുന്ന ഒരു പൈപ്പ്ലൈനായി ഇതിനെ കരുതുക.
ഒബ്സെർവബിൾസ് നിർമ്മിക്കുന്നു:
ഒബ്സെർവബിൾസ് നിർമ്മിക്കാൻ RxJS നിരവധി വഴികൾ നൽകുന്നു:
Observable.create()
: ഒബ്സെർവബിളിന്റെ പ്രവർത്തനത്തിൽ നിങ്ങൾക്ക് പൂർണ്ണ നിയന്ത്രണം നൽകുന്ന ഒരു ലോ-ലെവൽ രീതി.from()
: ഒരു അറേ, പ്രോമിസ്, ഇറ്ററബിൾ, അല്ലെങ്കിൽ ഒബ്സെർവബിൾ പോലുള്ള ഒബ്ജക്റ്റിനെ ഒരു ഒബ്സെർവബിൾ ആക്കി മാറ്റുന്നു.of()
: മൂല്യങ്ങളുടെ ഒരു ശ്രേണി പുറത്തുവിടുന്ന ഒരു ഒബ്സെർവബിൾ നിർമ്മിക്കുന്നു.interval()
: ഒരു നിശ്ചിത ഇടവേളയിൽ സംഖ്യകളുടെ ഒരു ശ്രേണി പുറത്തുവിടുന്ന ഒരു ഒബ്സെർവബിൾ നിർമ്മിക്കുന്നു.timer()
: ഒരു നിശ്ചിത കാലതാമസത്തിന് ശേഷം ഒരൊറ്റ മൂല്യം പുറത്തുവിടുന്ന, അല്ലെങ്കിൽ കാലതാമസത്തിന് ശേഷം ഒരു നിശ്ചിത ഇടവേളയിൽ സംഖ്യകളുടെ ഒരു ശ്രേണി പുറത്തുവിടുന്ന ഒരു ഒബ്സെർവബിൾ നിർമ്മിക്കുന്നു.fromEvent()
: ഒരു DOM എലമെന്റിൽ നിന്നോ മറ്റ് ഇവന്റ് ഉറവിടത്തിൽ നിന്നോ ഇവന്റുകൾ പുറത്തുവിടുന്ന ഒരു ഒബ്സെർവബിൾ നിർമ്മിക്കുന്നു.
ഉദാഹരണം: ഒരു അറേയിൽ നിന്ന് ഒബ്സെർവബിൾ നിർമ്മിക്കുന്നു
```javascript import { from } from 'rxjs'; const myArray = [1, 2, 3, 4, 5]; const myObservable = from(myArray); myObservable.subscribe( value => console.log('ലഭിച്ചത്:', value), error => console.error('പിശക്:', error), () => console.log('പൂർത്തിയായി') ); // ഔട്ട്പുട്ട്: // ലഭിച്ചത്: 1 // ലഭിച്ചത്: 2 // ലഭിച്ചത്: 3 // ലഭിച്ചത്: 4 // ലഭിച്ചത്: 5 // പൂർത്തിയായി ```
ഉദാഹരണം: ഒരു ഇവന്റിൽ നിന്ന് ഒബ്സെർവബിൾ നിർമ്മിക്കുന്നു
```javascript import { fromEvent } from 'rxjs'; const button = document.getElementById('myButton'); const clickObservable = fromEvent(button, 'click'); clickObservable.subscribe( event => console.log('ബട്ടൺ ക്ലിക്ക് ചെയ്തു!', event) ); ```
ഒബ്സെർവബിൾസിലേക്ക് സബ്സ്ക്രൈബ് ചെയ്യുന്നു:
ഒരു ഒബ്സെർവബിളിൽ നിന്ന് മൂല്യങ്ങൾ ലഭിക്കാൻ തുടങ്ങുന്നതിന്, നിങ്ങൾ subscribe()
രീതി ഉപയോഗിച്ച് അതിലേക്ക് സബ്സ്ക്രൈബ് ചെയ്യേണ്ടതുണ്ട്. subscribe()
രീതിക്ക് മൂന്ന് ആർഗ്യുമെന്റുകൾ വരെ സ്വീകരിക്കാൻ കഴിയും:
next
: ഒബ്സെർവബിൾ പുറത്തുവിടുന്ന ഓരോ മൂല്യത്തിനും വിളിക്കപ്പെടുന്ന ഒരു ഫംഗ്ഷൻ.error
: ഒബ്സെർവബിൾ ഒരു പിശക് പുറത്തുവിട്ടാൽ വിളിക്കപ്പെടുന്ന ഒരു ഫംഗ്ഷൻ.complete
: ഒബ്സെർവബിൾ പൂർത്തിയാകുമ്പോൾ (സ്ട്രീമിന്റെ അവസാനം സൂചിപ്പിക്കുമ്പോൾ) വിളിക്കപ്പെടുന്ന ഒരു ഫംഗ്ഷൻ.
subscribe()
രീതി ഒരു സബ്സ്ക്രിപ്ഷൻ ഒബ്ജക്റ്റ് തിരികെ നൽകുന്നു, ഇത് ഒബ്സെർവബിളും ഒബ്സെർവറും തമ്മിലുള്ള ബന്ധത്തെ പ്രതിനിധീകരിക്കുന്നു. ഒബ്സെർവബിളിൽ നിന്ന് അൺസബ്സ്ക്രൈബ് ചെയ്യാൻ നിങ്ങൾക്ക് സബ്സ്ക്രിപ്ഷൻ ഒബ്ജക്റ്റ് ഉപയോഗിക്കാം, ഇത് കൂടുതൽ മൂല്യങ്ങൾ പുറത്തുവിടുന്നത് തടയുന്നു.
ഒബ്സെർവബിൾസിൽ നിന്ന് അൺസബ്സ്ക്രൈബ് ചെയ്യുന്നു:
മെമ്മറി ലീക്കുകൾ തടയുന്നതിന് അൺസബ്സ്ക്രൈബ് ചെയ്യേണ്ടത് അത്യാവശ്യമാണ്, പ്രത്യേകിച്ചും ദീർഘകാലം നിലനിൽക്കുന്ന ഒബ്സെർവബിൾസ് അല്ലെങ്കിൽ ഇടയ്ക്കിടെ മൂല്യങ്ങൾ പുറത്തുവിടുന്ന ഒബ്സെർവബിൾസ് കൈകാര്യം ചെയ്യുമ്പോൾ. സബ്സ്ക്രിപ്ഷൻ ഒബ്ജക്റ്റിലെ unsubscribe()
രീതി വിളിച്ചുകൊണ്ട് നിങ്ങൾക്ക് ഒരു ഒബ്സെർവബിളിൽ നിന്ന് അൺസബ്സ്ക്രൈബ് ചെയ്യാം.
```javascript import { interval } from 'rxjs'; const myInterval = interval(1000); const subscription = myInterval.subscribe( value => console.log('ഇടവേള:', value) ); // 5 സെക്കൻഡിന് ശേഷം, അൺസബ്സ്ക്രൈബ് ചെയ്യുക setTimeout(() => { subscription.unsubscribe(); console.log('അൺസബ്സ്ക്രൈബ് ചെയ്തു!'); }, 5000); // ഔട്ട്പുട്ട് (ഏകദേശം): // ഇടവേള: 0 // ഇടവേള: 1 // ഇടവേള: 2 // ഇടവേള: 3 // ഇടവേള: 4 // അൺസബ്സ്ക്രൈബ് ചെയ്തു! ```
RxJS ഓപ്പറേറ്ററുകൾ: ഡാറ്റാ സ്ട്രീമുകളെ രൂപാന്തരപ്പെടുത്തുകയും ഫിൽട്ടർ ചെയ്യുകയും ചെയ്യുന്നു
RxJS ഓപ്പറേറ്ററുകൾ ഈ ലൈബ്രറിയുടെ ഹൃദയമാണ്. ഒബ്സെർവബിൾസിനെ ഡിക്ലറേറ്റീവും കമ്പോസബിളുമായ രീതിയിൽ രൂപാന്തരപ്പെടുത്താനും, ഫിൽട്ടർ ചെയ്യാനും, സംയോജിപ്പിക്കാനും, കൈകാര്യം ചെയ്യാനും അവ നിങ്ങളെ അനുവദിക്കുന്നു. ഓരോന്നും ഒരു പ്രത്യേക ഉദ്ദേശ്യം നിറവേറ്റുന്ന നിരവധി ഓപ്പറേറ്ററുകൾ ലഭ്യമാണ്. ഏറ്റവും സാധാരണയായി ഉപയോഗിക്കുന്ന ചില ഓപ്പറേറ്ററുകൾ താഴെ നൽകുന്നു:
രൂപാന്തരണ ഓപ്പറേറ്ററുകൾ (Transformation Operators):
map()
: ഒബ്സെർവബിൾ പുറത്തുവിടുന്ന ഓരോ മൂല്യത്തിലും ഒരു ഫംഗ്ഷൻ പ്രയോഗിക്കുകയും ഫലം പുറത്തുവിടുകയും ചെയ്യുന്നു. അറേകളിലെmap()
രീതിക്ക് സമാനം.pluck()
: ഒബ്സെർവബിൾ പുറത്തുവിടുന്ന ഓരോ മൂല്യത്തിൽ നിന്നും ഒരു നിർദ്ദിഷ്ട പ്രോപ്പർട്ടി വേർതിരിച്ചെടുക്കുന്നു.scan()
: സോഴ്സ് ഒബ്സെർവബിളിന് മുകളിൽ ഒരു അക്യുമുലേറ്റർ ഫംഗ്ഷൻ പ്രയോഗിക്കുകയും ഓരോ ഇടക്കാല ഫലവും തിരികെ നൽകുകയും ചെയ്യുന്നു.buffer()
: സോഴ്സ് ഒബ്സെർവബിളിൽ നിന്ന് മൂല്യങ്ങൾ ഒരു അറേയിലേക്ക് ശേഖരിക്കുകയും ഒരു നിർദ്ദിഷ്ട വ്യവസ്ഥ പാലിക്കുമ്പോൾ അറേ പുറത്തുവിടുകയും ചെയ്യുന്നു.window()
:buffer()
-ന് സമാനമാണ്, പക്ഷേ ഒരു അറേ പുറത്തുവിടുന്നതിന് പകരം, മൂല്യങ്ങളുടെ ഒരു വിൻഡോയെ പ്രതിനിധീകരിക്കുന്ന ഒരു ഒബ്സെർവബിൾ പുറത്തുവിടുന്നു.
ഉദാഹരണം: map()
ഓപ്പറേറ്റർ ഉപയോഗിക്കുന്നു
```javascript import { from } from 'rxjs'; import { map } from 'rxjs/operators'; const numbers = from([1, 2, 3, 4, 5]); const squaredNumbers = numbers.pipe( map(x => x * x) ); squaredNumbers.subscribe(value => console.log('വർഗ്ഗം:', value)); // ഔട്ട്പുട്ട്: // വർഗ്ഗം: 1 // വർഗ്ഗം: 4 // വർഗ്ഗം: 9 // വർഗ്ഗം: 16 // വർഗ്ഗം: 25 ```
ഫിൽട്ടറിംഗ് ഓപ്പറേറ്ററുകൾ:
filter()
: ഒരു നിർദ്ദിഷ്ട വ്യവസ്ഥ തൃപ്തിപ്പെടുത്തുന്ന മൂല്യങ്ങൾ മാത്രം പുറത്തുവിടുന്നു.debounceTime()
: പുതിയ മൂല്യങ്ങളൊന്നും പുറത്തുവിടാതെ ഒരു നിശ്ചിത സമയം കഴിയുന്നതുവരെ മൂല്യങ്ങളുടെ പുറത്തുവിടൽ വൈകിപ്പിക്കുന്നു. ഉപയോക്തൃ ഇൻപുട്ട് കൈകാര്യം ചെയ്യുന്നതിനും അമിതമായ അഭ്യർത്ഥനകൾ തടയുന്നതിനും ഇത് ഉപയോഗപ്രദമാണ്.distinctUntilChanged()
: മുൻ മൂല്യത്തിൽ നിന്ന് വ്യത്യസ്തമായ മൂല്യങ്ങൾ മാത്രം പുറത്തുവിടുന്നു.take()
: ഒബ്സെർവബിളിൽ നിന്നുള്ള ആദ്യത്തെ N മൂല്യങ്ങൾ മാത്രം പുറത്തുവിടുന്നു.skip()
: ഒബ്സെർവബിളിൽ നിന്നുള്ള ആദ്യത്തെ N മൂല്യങ്ങൾ ഒഴിവാക്കുകയും ശേഷിക്കുന്ന മൂല്യങ്ങൾ പുറത്തുവിടുകയും ചെയ്യുന്നു.
ഉദാഹരണം: filter()
ഓപ്പറേറ്റർ ഉപയോഗിക്കുന്നു
```javascript import { from } from 'rxjs'; import { filter } from 'rxjs/operators'; const numbers = from([1, 2, 3, 4, 5, 6]); const evenNumbers = numbers.pipe( filter(x => x % 2 === 0) ); evenNumbers.subscribe(value => console.log('ഇരട്ടസംഖ്യ:', value)); // ഔട്ട്പുട്ട്: // ഇരട്ടസംഖ്യ: 2 // ഇരട്ടസംഖ്യ: 4 // ഇരട്ടസംഖ്യ: 6 ```
കോമ്പിനേഷൻ ഓപ്പറേറ്ററുകൾ:
merge()
: ഒന്നിലധികം ഒബ്സെർവബിൾസിനെ ഒരൊറ്റ ഒബ്സെർവബിളിലേക്ക് ലയിപ്പിക്കുന്നു.concat()
: ഒന്നിലധികം ഒബ്സെർവബിൾസിനെ ഒരുമിപ്പിക്കുന്നു, ഓരോ ഒബ്സെർവബിളിൽ നിന്നും ക്രമത്തിൽ മൂല്യങ്ങൾ പുറത്തുവിടുന്നു.combineLatest()
: ഒന്നിലധികം ഒബ്സെർവബിൾസിൽ നിന്നുള്ള ഏറ്റവും പുതിയ മൂല്യങ്ങൾ സംയോജിപ്പിക്കുകയും ഏതെങ്കിലും സോഴ്സ് ഒബ്സെർവബിൾ ഒരു മൂല്യം പുറത്തുവിടുമ്പോഴെല്ലാം ഒരു പുതിയ മൂല്യം പുറത്തുവിടുകയും ചെയ്യുന്നു.zip()
: ഒന്നിലധികം ഒബ്സെർവബിൾസിൽ നിന്നുള്ള മൂല്യങ്ങളെ അവയുടെ ഇൻഡെക്സ് അടിസ്ഥാനമാക്കി സംയോജിപ്പിക്കുകയും ഓരോ കോമ്പിനേഷനും ഒരു പുതിയ മൂല്യം പുറത്തുവിടുകയും ചെയ്യുന്നു.withLatestFrom()
: മറ്റൊരു ഒബ്സെർവബിളിൽ നിന്നുള്ള ഏറ്റവും പുതിയ മൂല്യത്തെ സോഴ്സ് ഒബ്സെർവബിളിൽ നിന്നുള്ള നിലവിലെ മൂല്യവുമായി സംയോജിപ്പിക്കുന്നു.
ഉദാഹരണം: combineLatest()
ഓപ്പറേറ്റർ ഉപയോഗിക്കുന്നു
```javascript import { interval, combineLatest } from 'rxjs'; import { map } from 'rxjs/operators'; const interval1 = interval(1000); const interval2 = interval(2000); const combinedIntervals = combineLatest( interval1, interval2, (x, y) => `ഇടവേള 1: ${x}, ഇടവേള 2: ${y}` ); combinedIntervals.subscribe(value => console.log(value)); // ഔട്ട്പുട്ട് (ഏകദേശം): // ഇടവേള 1: 0, ഇടവേള 2: 0 // ഇടവേള 1: 1, ഇടവേള 2: 0 // ഇടവേള 1: 1, ഇടവേള 2: 1 // ഇടവേള 1: 2, ഇടവേള 2: 1 // ഇടവേള 1: 2, ഇടവേള 2: 2 // ... ```
സാധാരണ RxJS പാറ്റേണുകൾ
സാധാരണ അസിൻക്രണസ് പ്രോഗ്രാമിംഗ് ജോലികൾ ലളിതമാക്കാൻ കഴിയുന്ന നിരവധി ശക്തമായ പാറ്റേണുകൾ RxJS നൽകുന്നു:
ഡിബൗൺസിംഗ് (Debouncing):
debounceTime()
ഓപ്പറേറ്റർ ഉപയോഗിക്കുന്നത്, പുതിയ മൂല്യങ്ങളൊന്നും പുറത്തുവിടാതെ ഒരു നിശ്ചിത സമയം കഴിയുന്നത് വരെ മൂല്യങ്ങൾ പുറത്തുവിടുന്നത് വൈകിപ്പിക്കാനാണ്. സെർച്ച് ചോദ്യങ്ങൾ അല്ലെങ്കിൽ ഫോം സമർപ്പണങ്ങൾ പോലുള്ള ഉപയോക്തൃ ഇൻപുട്ടുകൾ കൈകാര്യം ചെയ്യുന്നതിന് ഇത് പ്രത്യേകിച്ചും ഉപയോഗപ്രദമാണ്, കാരണം ഇത് സെർവറിലേക്കുള്ള അമിതമായ അഭ്യർത്ഥനകൾ തടയുന്നു.
ഉദാഹരണം: ഒരു സെർച്ച് ഇൻപുട്ട് ഡിബൗൺസ് ചെയ്യുന്നു
```javascript import { fromEvent } from 'rxjs'; import { map, debounceTime, distinctUntilChanged } from 'rxjs/operators'; const searchInput = document.getElementById('searchInput'); const searchObservable = fromEvent(searchInput, 'keyup').pipe( map((event: any) => event.target.value), debounceTime(300), // ഓരോ കീ പ്രസ്സിനും ശേഷം 300ms കാത്തിരിക്കുക distinctUntilChanged() // മൂല്യം മാറിയിട്ടുണ്ടെങ്കിൽ മാത്രം പുറത്തുവിടുക ); searchObservable.subscribe(searchTerm => { console.log('തിരയുന്നു:', searchTerm); // പദം തിരയാൻ ഒരു API അഭ്യർത്ഥന നടത്തുക }); ```
ത്രോട്ടിലിംഗ് (Throttling):
throttleTime()
ഓപ്പറേറ്റർ ഒരു ഒബ്സെർവബിളിൽ നിന്ന് മൂല്യങ്ങൾ പുറത്തുവിടുന്ന നിരക്ക് പരിമിതപ്പെടുത്തുന്നു. ഇത് ഒരു നിർദ്ദിഷ്ട സമയപരിധിക്കുള്ളിൽ പുറത്തുവിടുന്ന ആദ്യത്തെ മൂല്യം പുറത്തുവിടുകയും വിൻഡോ അടയുന്നതുവരെ തുടർന്നുള്ള മൂല്യങ്ങളെ അവഗണിക്കുകയും ചെയ്യുന്നു. സ്ക്രോൾ ഇവന്റുകൾ അല്ലെങ്കിൽ റീസൈസ് ഇവന്റുകൾ പോലുള്ള ഇവന്റുകളുടെ ആവൃത്തി പരിമിതപ്പെടുത്തുന്നതിന് ഇത് ഉപയോഗപ്രദമാണ്.
സ്വിച്ചിംഗ് (Switching):
switchMap()
ഓപ്പറേറ്റർ ഉപയോഗിക്കുന്നത്, സോഴ്സ് ഒബ്സെർവബിളിൽ നിന്ന് ഒരു പുതിയ മൂല്യം പുറത്തുവിടുമ്പോഴെല്ലാം ഒരു പുതിയ ഒബ്സെർവബിളിലേക്ക് മാറാനാണ്. ഒരു പുതിയ അഭ്യർത്ഥന ആരംഭിക്കുമ്പോൾ ശേഷിക്കുന്ന അഭ്യർത്ഥനകൾ റദ്ദാക്കുന്നതിന് ഇത് ഉപയോഗപ്രദമാണ്. ഉദാഹരണത്തിന്, ഉപയോക്താവ് സെർച്ച് ഇൻപുട്ടിൽ ഒരു പുതിയ അക്ഷരം ടൈപ്പ് ചെയ്യുമ്പോൾ മുൻപത്തെ സെർച്ച് അഭ്യർത്ഥന റദ്ദാക്കാൻ നിങ്ങൾക്ക് switchMap()
ഉപയോഗിക്കാം.
ഉദാഹരണം: ടൈപ്പ്ഹെഡ് സെർച്ചിനായി switchMap()
ഉപയോഗിക്കുന്നു
```javascript import { fromEvent, of } from 'rxjs'; import { map, debounceTime, distinctUntilChanged, switchMap, catchError } from 'rxjs/operators'; const searchInput = document.getElementById('searchInput'); const searchObservable = fromEvent(searchInput, 'keyup').pipe( map((event: any) => event.target.value), debounceTime(300), distinctUntilChanged(), switchMap(searchTerm => { // പദം തിരയാൻ ഒരു API അഭ്യർത്ഥന നടത്തുക return searchAPI(searchTerm).pipe( catchError(error => { console.error('തിരയുമ്പോൾ പിശക്:', error); return of([]); // പിശക് സംഭവിച്ചാൽ ഒരു ശൂന്യമായ അറേ തിരികെ നൽകുക }) ); }) ); searchObservable.subscribe(results => { console.log('സെർച്ച് ഫലങ്ങൾ:', results); // സെർച്ച് ഫലങ്ങൾ ഉപയോഗിച്ച് UI അപ്ഡേറ്റ് ചെയ്യുക }); function searchAPI(searchTerm: string) { // ഒരു API അഭ്യർത്ഥന അനുകരിക്കുക return of([`${searchTerm} എന്നതിനായുള്ള ഫലം 1`, `${searchTerm} എന്നതിനായുള്ള ഫലം 2`]); } ```
RxJS-ന്റെ പ്രായോഗിക പ്രയോഗങ്ങൾ
RxJS എന്നത് വിപുലമായ ആപ്ലിക്കേഷനുകളിൽ ഉപയോഗിക്കാൻ കഴിയുന്ന ഒരു വൈവിധ്യമാർന്ന ലൈബ്രറിയാണ്. ചില സാധാരണ ഉപയോഗങ്ങൾ ഇതാ:
- ഉപയോക്തൃ ഇൻപുട്ട് കൈകാര്യം ചെയ്യൽ: കീ പ്രസ്സുകൾ, മൗസ് ക്ലിക്കുകൾ, ഫോം സമർപ്പിക്കലുകൾ തുടങ്ങിയ ഉപയോക്തൃ ഇൻപുട്ട് ഇവന്റുകൾ കൈകാര്യം ചെയ്യാൻ RxJS ഉപയോഗിക്കാം. പ്രകടനം ഒപ്റ്റിമൈസ് ചെയ്യുന്നതിനും അമിതമായ അഭ്യർത്ഥനകൾ തടയുന്നതിനും
debounceTime()
,throttleTime()
പോലുള്ള ഓപ്പറേറ്ററുകൾ ഉപയോഗിക്കാം. - അസിൻക്രണസ് പ്രവർത്തനങ്ങൾ കൈകാര്യം ചെയ്യൽ: നെറ്റ്വർക്ക് അഭ്യർത്ഥനകളും ടൈമറുകളും പോലുള്ള അസിൻക്രണസ് പ്രവർത്തനങ്ങൾ കൈകാര്യം ചെയ്യുന്നതിനുള്ള ശക്തമായ മാർഗ്ഗം RxJS നൽകുന്നു. ഒരേസമയം നടക്കുന്ന അഭ്യർത്ഥനകൾ കൈകാര്യം ചെയ്യാനും ശേഷിക്കുന്ന അഭ്യർത്ഥനകൾ റദ്ദാക്കാനും
switchMap()
,mergeMap()
പോലുള്ള ഓപ്പറേറ്ററുകൾ ഉപയോഗിക്കാം. - തത്സമയ ആപ്ലിക്കേഷനുകൾ നിർമ്മിക്കൽ: ചാറ്റ് ആപ്ലിക്കേഷനുകളും ഡാഷ്ബോർഡുകളും പോലുള്ള തത്സമയ ആപ്ലിക്കേഷനുകൾ നിർമ്മിക്കുന്നതിന് RxJS വളരെ അനുയോജ്യമാണ്. വെബ്സോക്കറ്റുകളിൽ നിന്നോ സെർവർ-സെന്റ് ഇവന്റുകളിൽ നിന്നോ (SSE) ഉള്ള ഡാറ്റാ സ്ട്രീമുകളെ പ്രതിനിധീകരിക്കാൻ ഒബ്സെർവബിൾസ് ഉപയോഗിക്കാം.
- സ്റ്റേറ്റ് മാനേജ്മെന്റ്: ആംഗുലർ, റിയാക്റ്റ്, വ്യൂ.ജെഎസ് പോലുള്ള ഫ്രെയിംവർക്കുകളിൽ ഒരു സ്റ്റേറ്റ് മാനേജ്മെന്റ് സൊല്യൂഷനായി RxJS ഉപയോഗിക്കാം. ആപ്ലിക്കേഷൻ സ്റ്റേറ്റിനെ പ്രതിനിധീകരിക്കാൻ ഒബ്സെർവബിൾസ് ഉപയോഗിക്കാം, കൂടാതെ ഉപയോക്തൃ പ്രവർത്തനങ്ങൾക്കോ ഇവന്റുകൾക്കോ പ്രതികരണമായി സ്റ്റേറ്റിനെ രൂപാന്തരപ്പെടുത്താനും അപ്ഡേറ്റ് ചെയ്യാനും ഓപ്പറേറ്ററുകൾ ഉപയോഗിക്കാം.
പ്രശസ്തമായ ഫ്രെയിംവർക്കുകളോടൊപ്പം RxJS
ആംഗുലർ (Angular):
അസിൻക്രണസ് പ്രവർത്തനങ്ങൾ കൈകാര്യം ചെയ്യുന്നതിനും ഡാറ്റാ സ്ട്രീമുകൾ നിയന്ത്രിക്കുന്നതിനും ആംഗുലർ RxJS-നെ വളരെയധികം ആശ്രയിക്കുന്നു. ആംഗുലറിലെ HttpClient
സേവനം ഒബ്സെർവബിൾസ് തിരികെ നൽകുന്നു, കൂടാതെ API അഭ്യർത്ഥനകളിൽ നിന്ന് ലഭിക്കുന്ന ഡാറ്റയെ രൂപാന്തരപ്പെടുത്തുന്നതിനും ഫിൽട്ടർ ചെയ്യുന്നതിനും RxJS ഓപ്പറേറ്ററുകൾ വ്യാപകമായി ഉപയോഗിക്കുന്നു. ആംഗുലറിന്റെ ചേഞ്ച് ഡിറ്റക്ഷൻ മെക്കാനിസം ഡാറ്റാ മാറ്റങ്ങളോട് പ്രതികരിച്ച് UI കാര്യക്ഷമമായി അപ്ഡേറ്റ് ചെയ്യുന്നതിന് RxJS-നെ പ്രയോജനപ്പെടുത്തുന്നു.
ഉദാഹരണം: ആംഗുലറിന്റെ HttpClient-നൊപ്പം RxJS ഉപയോഗിക്കുന്നു
```typescript
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class DataService {
private apiUrl = 'https://api.example.com/data';
constructor(private http: HttpClient) { }
getData(): Observable
റിയാക്റ്റ് (React):
റിയാക്റ്റിന് RxJS-നായി ബിൽറ്റ്-ഇൻ പിന്തുണയില്ലെങ്കിലും, rxjs-hooks
അല്ലെങ്കിൽ use-rx
പോലുള്ള ലൈബ്രറികൾ ഉപയോഗിച്ച് ഇത് എളുപ്പത്തിൽ സംയോജിപ്പിക്കാൻ കഴിയും. ഈ ലൈബ്രറികൾ റിയാക്റ്റ് ഘടകങ്ങൾക്കുള്ളിൽ ഒബ്സെർവബിൾസിലേക്ക് സബ്സ്ക്രൈബ് ചെയ്യാനും സബ്സ്ക്രിപ്ഷനുകൾ കൈകാര്യം ചെയ്യാനും നിങ്ങളെ അനുവദിക്കുന്ന കസ്റ്റം ഹുക്കുകൾ നൽകുന്നു. അസിൻക്രണസ് ഡാറ്റാ ഫെച്ചിംഗ്, കമ്പോണന്റ് സ്റ്റേറ്റ് മാനേജ്മെൻറ്, റിയാക്ടീവ് UI-കൾ നിർമ്മിക്കൽ എന്നിവയ്ക്കായി റിയാക്റ്റിൽ RxJS ഉപയോഗിക്കാം.
ഉദാഹരണം: റിയാക്റ്റ് ഹുക്കുകളോടൊപ്പം RxJS ഉപയോഗിക്കുന്നു
```javascript import React, { useState, useEffect } from 'react'; import { Subject } from 'rxjs'; import { scan } from 'rxjs/operators'; function Counter() { const [count, setCount] = useState(0); const increment$ = new Subject(); useEffect(() => { const subscription = increment$.pipe( scan(acc => acc + 1, 0) ).subscribe(setCount); return () => subscription.unsubscribe(); }, []); return (
എണ്ണം: {count}
വ്യൂ.ജെഎസ് (Vue.js):
വ്യൂ.ജെഎസിനും നേറ്റീവ് RxJS സംയോജനമില്ല, പക്ഷേ ഇത് vue-rx
പോലുള്ള ലൈബ്രറികൾ ഉപയോഗിച്ചോ അല്ലെങ്കിൽ വ്യൂ കമ്പോണന്റുകൾക്കുള്ളിൽ സബ്സ്ക്രിപ്ഷനുകൾ നേരിട്ട് കൈകാര്യം ചെയ്തോ ഉപയോഗിക്കാം. റിയാക്റ്റിലെ പോലെ, അസിൻക്രണസ് ഡാറ്റാ ഫെച്ചിംഗ്, കമ്പോണന്റ് സ്റ്റേറ്റ് മാനേജ്മെൻറ് തുടങ്ങിയ സമാന ആവശ്യങ്ങൾക്കായി വ്യൂ.ജെഎസിൽ RxJS ഉപയോഗിക്കാം.
RxJS ഉപയോഗിക്കുന്നതിനുള്ള മികച്ച രീതികൾ
- ഒബ്സെർവബിൾസിൽ നിന്ന് അൺസബ്സ്ക്രൈബ് ചെയ്യുക: മെമ്മറി ലീക്കുകൾ തടയുന്നതിന് ഇനി ആവശ്യമില്ലാത്തപ്പോൾ എപ്പോഴും ഒബ്സെർവബിൾസിൽ നിന്ന് അൺസബ്സ്ക്രൈബ് ചെയ്യുക. അൺസബ്സ്ക്രൈബ് ചെയ്യുന്നതിന്
subscribe()
രീതി തിരികെ നൽകുന്ന സബ്സ്ക്രിപ്ഷൻ ഒബ്ജക്റ്റ് ഉപയോഗിക്കുക. pipe()
രീതി ഉപയോഗിക്കുക: ഓപ്പറേറ്ററുകളെ ഒരുമിച്ച് വായിക്കാവുന്നതും പരിപാലിക്കാൻ എളുപ്പമുള്ളതുമായ രീതിയിൽ ബന്ധിപ്പിക്കുന്നതിന്pipe()
രീതി ഉപയോഗിക്കുക.- പിശകുകൾ ഭംഗിയായി കൈകാര്യം ചെയ്യുക: പിശകുകൾ കൈകാര്യം ചെയ്യാനും അവ ഒബ്സെർവബിൾ ശൃംഖലയിലൂടെ മുകളിലേക്ക് വ്യാപിക്കുന്നത് തടയാനും
catchError()
ഓപ്പറേറ്റർ ഉപയോഗിക്കുക. - ശരിയായ ഓപ്പറേറ്ററുകൾ തിരഞ്ഞെടുക്കുക: നിങ്ങളുടെ പ്രത്യേക ഉപയോഗത്തിന് അനുയോജ്യമായ ഓപ്പറേറ്ററുകൾ തിരഞ്ഞെടുക്കുക. RxJS വിപുലമായ ഓപ്പറേറ്ററുകൾ നൽകുന്നു, അതിനാൽ അവയുടെ ഉദ്ദേശ്യവും പ്രവർത്തനവും മനസ്സിലാക്കേണ്ടത് പ്രധാനമാണ്.
- ഒബ്സെർവബിൾസ് ലളിതമായി സൂക്ഷിക്കുക: അമിതമായി സങ്കീർണ്ണമായ ഒബ്സെർവബിൾസ് നിർമ്മിക്കുന്നത് ഒഴിവാക്കുക. സങ്കീർണ്ണമായ പ്രവർത്തനങ്ങളെ ചെറുതും കൈകാര്യം ചെയ്യാൻ എളുപ്പമുള്ളതുമായ ഒബ്സെർവബിൾസ് ആയി വിഭജിക്കുക.
വിപുലമായ RxJS ആശയങ്ങൾ
സബ്ജക്ട്സ് (Subjects):
സബ്ജക്ട്സ് ഒബ്സെർവബിൾസായും ഒബ്സെർവേഴ്സായും പ്രവർത്തിക്കുന്നു. ഒന്നിലധികം സബ്സ്ക്രൈബർമാർക്ക് ഡാറ്റ മൾട്ടികാസ്റ്റ് ചെയ്യാനും സ്ട്രീമിലേക്ക് ഡാറ്റ പുഷ് ചെയ്യാനും അവ നിങ്ങളെ അനുവദിക്കുന്നു. വിവിധതരം സബ്ജക്ട്സ് ഉണ്ട്, അവയിൽ ചിലത്:
- Subject: എല്ലാ സബ്സ്ക്രൈബർമാർക്കും മൂല്യങ്ങൾ മൾട്ടികാസ്റ്റ് ചെയ്യുന്ന ഒരു അടിസ്ഥാന സബ്ജക്റ്റ്.
- BehaviorSubject: ഒരു പ്രാരംഭ മൂല്യം ആവശ്യമാണ്, കൂടാതെ പുതിയ സബ്സ്ക്രൈബർമാർക്ക് നിലവിലെ മൂല്യം പുറത്തുവിടുന്നു.
- ReplaySubject: ഒരു നിശ്ചിത എണ്ണം മൂല്യങ്ങൾ ബഫർ ചെയ്യുകയും പുതിയ സബ്സ്ക്രൈബർമാർക്ക് അവ വീണ്ടും പ്ലേ ചെയ്യുകയും ചെയ്യുന്നു.
- AsyncSubject: ഒബ്സെർവബിൾ പൂർത്തിയാകുമ്പോൾ അവസാനത്തെ മൂല്യം മാത്രം പുറത്തുവിടുന്നു.
ഷെഡ്യൂളറുകൾ (Schedulers):
ഷെഡ്യൂളറുകൾ ഒബ്സെർവബിൾസിന്റെ കൺകറൻസി നിയന്ത്രിക്കുന്നു. കോഡ് സിൻക്രണസ് ആയോ അസിൻക്രണസ് ആയോ, വ്യത്യസ്ത ത്രെഡുകളിലോ, അല്ലെങ്കിൽ നിർദ്ദിഷ്ട കാലതാമസത്തോടെയോ എക്സിക്യൂട്ട് ചെയ്യാൻ അവ നിങ്ങളെ അനുവദിക്കുന്നു. RxJS-ൽ നിരവധി ബിൽറ്റ്-ഇൻ ഷെഡ്യൂളറുകൾ ഉണ്ട്, അവയിൽ ചിലത്:
queueScheduler
: നിലവിലെ എക്സിക്യൂഷൻ കോൺടെക്സ്റ്റിന് ശേഷം, നിലവിലെ ജാവാസ്ക്രിപ്റ്റ് ത്രെഡിൽ ടാസ്ക്കുകൾ എക്സിക്യൂട്ട് ചെയ്യാൻ ഷെഡ്യൂൾ ചെയ്യുന്നു.asapScheduler
: നിലവിലെ എക്സിക്യൂഷൻ കോൺടെക്സ്റ്റിന് ശേഷം കഴിയുന്നത്ര വേഗത്തിൽ, നിലവിലെ ജാവാസ്ക്രിപ്റ്റ് ത്രെഡിൽ ടാസ്ക്കുകൾ എക്സിക്യൂട്ട് ചെയ്യാൻ ഷെഡ്യൂൾ ചെയ്യുന്നു.asyncScheduler
:setTimeout
അല്ലെങ്കിൽsetInterval
ഉപയോഗിച്ച് അസിൻക്രണസ് ആയി ടാസ്ക്കുകൾ എക്സിക്യൂട്ട് ചെയ്യാൻ ഷെഡ്യൂൾ ചെയ്യുന്നു.animationFrameScheduler
: അടുത്ത ആനിമേഷൻ ഫ്രെയിമിൽ ടാസ്ക്കുകൾ എക്സിക്യൂട്ട് ചെയ്യാൻ ഷെഡ്യൂൾ ചെയ്യുന്നു.
ഉപസംഹാരം
ജാവാസ്ക്രിപ്റ്റിൽ റിയാക്ടീവ് ആപ്ലിക്കേഷനുകൾ നിർമ്മിക്കുന്നതിനുള്ള ശക്തമായ ഒരു ലൈബ്രറിയാണ് RxJS. ഒബ്സെർവബിൾസ്, ഓപ്പറേറ്ററുകൾ, സാധാരണ പാറ്റേണുകൾ എന്നിവയിൽ വൈദഗ്ദ്ധ്യം നേടുന്നതിലൂടെ, നിങ്ങൾക്ക് കൂടുതൽ പ്രതികരണശേഷിയുള്ളതും, വികസിപ്പിക്കാവുന്നതും, പരിപാലിക്കാൻ എളുപ്പമുള്ളതുമായ ആപ്ലിക്കേഷനുകൾ നിർമ്മിക്കാൻ കഴിയും. നിങ്ങൾ ആംഗുലർ, റിയാക്റ്റ്, വ്യൂ.ജെഎസ്, അല്ലെങ്കിൽ വാനില ജാവാസ്ക്രിപ്റ്റ് എന്നിവ ഉപയോഗിച്ച് പ്രവർത്തിക്കുകയാണെങ്കിലും, അസിൻക്രണസ് ഡാറ്റാ സ്ട്രീമുകൾ കൈകാര്യം ചെയ്യാനും സങ്കീർണ്ണമായ UI-കൾ നിർമ്മിക്കാനുമുള്ള നിങ്ങളുടെ കഴിവിനെ RxJS കാര്യമായി മെച്ചപ്പെടുത്തും.
RxJS ഉപയോഗിച്ച് റിയാക്ടീവ് പ്രോഗ്രാമിംഗിന്റെ ശക്തി സ്വീകരിക്കുക, നിങ്ങളുടെ ജാവാസ്ക്രിപ്റ്റ് ആപ്ലിക്കേഷനുകൾക്കായി പുതിയ സാധ്യതകൾ തുറക്കുക!