RxJS yordamida JavaScript-da Reaktiv Dasturlashni o'rganing. Sezgir va kengaytiriladigan ilovalar yaratish uchun Observable oqimlari, patternlar va amaliy qo'llanmalarni o'rganing.
JavaScript Reaktiv Dasturlash: RxJS Patternlari va Observable Oqimlari
Zamonaviy veb-ishlab chiqishning doimiy rivojlanayotgan landshaftida sezgir, kengaytiriladigan va qo'llab-quvvatlanadigan ilovalar yaratish juda muhimdir. Reaktiv Dasturlash (RD) asinxron ma'lumotlar oqimlarini boshqarish va o'zgarishlarni ilovangiz bo'ylab tarqatish uchun kuchli paradigma taqdim etadi. JavaScript-da RD ni amalga oshirish uchun mashhur kutubxonalar orasida RxJS (Reactive Extensions for JavaScript) mustahkam va ko'p qirrali vosita sifatida ajralib turadi.
Reaktiv Dasturlash nima?
Asosan, Reaktiv Dasturlash asinxron ma'lumotlar oqimlari va o'zgarishlarning tarqalishi bilan ishlashga qaratilgan. Bir katakchani yangilash avtomatik ravishda bog'liq formulalarni qayta hisoblaydigan elektron jadvalni tasavvur qiling. Bu RD ning mohiyati – ma'lumotlar o'zgarishlariga deklarativ va samarali tarzda reaksiya bildirish.
An'anaviy imperativ dasturlash ko'pincha holatni boshqarishni va hodisalarga javoban komponentlarni qo'lda yangilashni o'z ichiga oladi. Bu, ayniqsa, tarmoq so'rovlari yoki foydalanuvchi o'zaro ta'sirlari kabi asinxron operatsiyalar bilan ishlaganda murakkab va xatolarga moyil kodga olib kelishi mumkin. RD buni hamma narsani ma'lumotlar oqimi sifatida ko'rib chiqish va bu oqimlarni o'zgartirish, filtrlash va birlashtirish uchun operatorlarni taqdim etish orqali soddalashtiradi.
RxJS bilan tanishuv: JavaScript uchun Reaktiv Kengaytmalar
RxJS - bu observable ketma-ketliklari yordamida asinxron va hodisalarga asoslangan dasturlarni yaratish uchun kutubxona. U ma'lumotlar oqimlarini osongina boshqarish imkonini beruvchi kuchli operatorlar to'plamini taqdim etadi. RxJS hodisalar yoki ma'lumotlar ketma-ketligini samarali boshqarish uchun Observer patterni, Iterator patterni va Funksional Dasturlash konsepsiyalariga asoslanadi.
RxJS dagi asosiy tushunchalar:
- Observables: Bir yoki bir nechta Observerlar tomonidan kuzatilishi mumkin bo'lgan ma'lumotlar oqimini ifodalaydi. Ular "dangasa" bo'lib, faqat obuna bo'linganida qiymatlarni chiqara boshlaydi.
- Observers: Observables tomonidan chiqarilgan ma'lumotlarni iste'mol qiladi. Ularning uchta metodi bor:
next()
qiymatlarni qabul qilish uchun,error()
xatoliklarni qayta ishlash uchun vacomplete()
oqimning tugashini bildirish uchun. - Operators: Observables ni o'zgartiradigan, filtrlaydigan, birlashtiradigan yoki boshqaradigan funksiyalar. RxJS turli maqsadlar uchun keng ko'lamli operatorlarni taqdim etadi.
- Subjects: Ham Observable, ham Observer sifatida ishlaydi, bu sizga ma'lumotlarni bir nechta obunachiga ko'p yo'nalishli uzatish va oqimga ma'lumotlarni yuborish imkonini beradi.
- Schedulers: Observables ning bir vaqtda ishlashini nazorat qiladi, bu sizga kodni sinxron yoki asinxron, turli xil oqimlarda yoki ma'lum bir kechikish bilan bajarish imkonini beradi.
Observable Oqimlari batafsil
Observables RxJS ning asosidir. Ular vaqt o'tishi bilan kuzatilishi mumkin bo'lgan ma'lumotlar oqimini ifodalaydi. Observable o'z obunachilariga qiymatlarni chiqaradi, ular keyin bu qiymatlarni qayta ishlashi yoki ularga reaksiya bildirishi mumkin. Buni ma'lumotlar manbadan bir yoki bir nechta iste'molchilarga oqib o'tadigan quvur deb o'ylang.
Observables yaratish:
RxJS Observables yaratishning bir necha usullarini taqdim etadi:
Observable.create()
: Observable xatti-harakati ustidan to'liq nazoratni beradigan past darajali usul.from()
: Massiv, promise, iterable yoki Observable-ga o'xshash ob'ektni Observable-ga o'zgartiradi.of()
: Qiymatlar ketma-ketligini chiqaradigan Observable yaratadi.interval()
: Belgilangan intervalda raqamlar ketma-ketligini chiqaradigan Observable yaratadi.timer()
: Belgilangan kechikishdan so'ng bitta qiymat chiqaradigan yoki kechikishdan so'ng belgilangan intervalda raqamlar ketma-ketligini chiqaradigan Observable yaratadi.fromEvent()
: DOM elementi yoki boshqa hodisa manbasidan hodisalarni chiqaradigan Observable yaratadi.
Misol: Massivdan Observable yaratish
```javascript import { from } from 'rxjs'; const myArray = [1, 2, 3, 4, 5]; const myObservable = from(myArray); myObservable.subscribe( value => console.log('Qabul qilindi:', value), error => console.error('Xatolik:', error), () => console.log('Yakunlandi') ); // Natija: // Qabul qilindi: 1 // Qabul qilindi: 2 // Qabul qilindi: 3 // Qabul qilindi: 4 // Qabul qilindi: 5 // Yakunlandi ```
Misol: Hodisadan Observable yaratish
```javascript import { fromEvent } from 'rxjs'; const button = document.getElementById('myButton'); const clickObservable = fromEvent(button, 'click'); clickObservable.subscribe( event => console.log('Tugma bosildi!', event) ); ```
Observables ga obuna bo'lish:
Observable dan qiymatlarni qabul qilishni boshlash uchun unga subscribe()
metodi yordamida obuna bo'lishingiz kerak. subscribe()
metodi uchta argumentgacha qabul qilishi mumkin:
next
: Observable tomonidan chiqarilgan har bir qiymat uchun chaqiriladigan funksiya.error
: Observable xatolik chiqarsa, chaqiriladigan funksiya.complete
: Observable tugallanganda (oqimning tugashini bildirsa) chaqiriladigan funksiya.
subscribe()
metodi Observable va Observer o'rtasidagi aloqani ifodalovchi Subscription obyektini qaytaradi. Siz Subscription obyektidan Observable dan obunani bekor qilish uchun foydalanishingiz mumkin, bu esa keyingi qiymatlarning chiqarilishini oldini oladi.
Observables dan obunani bekor qilish:
Obunani bekor qilish, ayniqsa uzoq muddatli yoki tez-tez qiymat chiqaradigan Observables bilan ishlaganda, xotira sizib chiqishining oldini olish uchun juda muhimdir. Siz Observable dan obunani Subscription obyektidagi unsubscribe()
metodini chaqirish orqali bekor qilishingiz mumkin.
```javascript import { interval } from 'rxjs'; const myInterval = interval(1000); const subscription = myInterval.subscribe( value => console.log('Interval:', value) ); // 5 soniyadan so'ng obunani bekor qiling setTimeout(() => { subscription.unsubscribe(); console.log('Obuna bekor qilindi!'); }, 5000); // Natija (taxminan): // Interval: 0 // Interval: 1 // Interval: 2 // Interval: 3 // Interval: 4 // Obuna bekor qilindi! ```
RxJS Operatorlari: Ma'lumotlar Oqimlarini O'zgartirish va Filtrlash
RxJS operatorlari kutubxonaning yuragi hisoblanadi. Ular sizga Observables ni deklarativ va kompozitsion tarzda o'zgartirish, filtrlash, birlashtirish va boshqarish imkonini beradi. Har biri o'ziga xos maqsadga xizmat qiladigan ko'plab operatorlar mavjud. Mana eng ko'p ishlatiladigan operatorlardan ba'zilari:
O'zgartirish Operatorlari:
map()
: Observable tomonidan chiqarilgan har bir qiymatga funksiya qo'llaydi va natijani chiqaradi. Massivlardagimap()
metodiga o'xshaydi.pluck()
: Observable tomonidan chiqarilgan har bir qiymatdan ma'lum bir xususiyatni ajratib oladi.scan()
: Manba Observable ustida akkumulyator funksiyasini qo'llaydi va har bir oraliq natijani qaytaradi.buffer()
: Manba Observable dan qiymatlarni massivga to'playdi va ma'lum bir shart bajarilganda massivni chiqaradi.window()
:buffer()
ga o'xshaydi, lekin massiv chiqarish o'rniga, u qiymatlar oynasini ifodalovchi Observable chiqaradi.
Misol: map()
operatoridan foydalanish
```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('Kvadrat:', value)); // Natija: // Kvadrat: 1 // Kvadrat: 4 // Kvadrat: 9 // Kvadrat: 16 // Kvadrat: 25 ```
Filtrlash Operatorlari:
filter()
: Faqat ma'lum bir shartni qanoatlantiradigan qiymatlarni chiqaradi.debounceTime()
: Hech qanday yangi qiymat chiqmaguncha ma'lum bir vaqt o'tgandan so'ng qiymatlarni chiqarishni kechiktiradi. Foydalanuvchi kiritishlarini boshqarish va ortiqcha so'rovlarning oldini olish uchun foydalidir.distinctUntilChanged()
: Faqat oldingi qiymatdan farq qiladigan qiymatlarni chiqaradi.take()
: Observable dan faqat birinchi N ta qiymatni chiqaradi.skip()
: Observable dan birinchi N ta qiymatni o'tkazib yuboradi va qolgan qiymatlarni chiqaradi.
Misol: filter()
operatoridan foydalanish
```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('Juft:', value)); // Natija: // Juft: 2 // Juft: 4 // Juft: 6 ```
Birlashtirish Operatorlari:
merge()
: Bir nechta Observables ni bitta Observable ga birlashtiradi.concat()
: Bir nechta Observables ni birlashtiradi va har bir Observable dan qiymatlarni ketma-ket chiqaradi.combineLatest()
: Bir nechta Observables dan eng so'nggi qiymatlarni birlashtiradi va manba Observables dan birortasi qiymat chiqarganda yangi qiymat chiqaradi.zip()
: Bir nechta Observables dan qiymatlarni ularning indeksiga qarab birlashtiradi va har bir kombinatsiya uchun yangi qiymat chiqaradi.withLatestFrom()
: Boshqa Observable dan eng so'nggi qiymatni manba Observable dan joriy qiymat bilan birlashtiradi.
Misol: combineLatest()
operatoridan foydalanish
```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) => `Interval 1: ${x}, Interval 2: ${y}` ); combinedIntervals.subscribe(value => console.log(value)); // Natija (taxminan): // Interval 1: 0, Interval 2: 0 // Interval 1: 1, Interval 2: 0 // Interval 1: 1, Interval 2: 1 // Interval 1: 2, Interval 2: 1 // Interval 1: 2, Interval 2: 2 // ... ```
Umumiy RxJS Patternlari
RxJS umumiy asinxron dasturlash vazifalarini soddalashtirishi mumkin bo'lgan bir nechta kuchli patternlarni taqdim etadi:
Debouncing:
debounceTime()
operatori qiymatlarni chiqarishni, yangi qiymatlar chiqmaguncha ma'lum bir vaqt o'tgandan so'ng kechiktirish uchun ishlatiladi. Bu, ayniqsa, qidiruv so'rovlari yoki forma yuborish kabi foydalanuvchi kiritishlarini boshqarishda foydalidir, chunki bu serverga ortiqcha so'rovlar yuborilishining oldini oladi.
Misol: Qidiruv maydonini Debouncing qilish
```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), // Har bir klavish bosilgandan so'ng 300ms kuting distinctUntilChanged() // Faqat qiymat o'zgargan bo'lsa, chiqaring ); searchObservable.subscribe(searchTerm => { console.log('Qidirilmoqda:', searchTerm); // Atama bo'yicha qidirish uchun API so'rovini yuboring }); ```
Throttling:
throttleTime()
operatori Observable dan qiymatlar chiqarilish tezligini cheklaydi. U belgilangan vaqt oralig'ida chiqarilgan birinchi qiymatni chiqaradi va oyna yopilguncha keyingi qiymatlarni e'tiborsiz qoldiradi. Bu aylantirish yoki o'lchamni o'zgartirish hodisalari kabi hodisalar chastotasini cheklash uchun foydalidir.
O'zgartirish (Switching):
switchMap()
operatori manba Observable dan yangi qiymat chiqarilganda yangi Observable ga o'tish uchun ishlatiladi. Bu yangi so'rov boshlanganda kutilayotgan so'rovlarni bekor qilish uchun foydalidir. Masalan, foydalanuvchi qidiruv maydoniga yangi belgi kiritganda oldingi qidiruv so'rovini bekor qilish uchun switchMap()
dan foydalanishingiz mumkin.
Misol: Typeahead qidiruvi uchun switchMap()
dan foydalanish
```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 => { // Atama bo'yicha qidirish uchun API so'rovini yuboring return searchAPI(searchTerm).pipe( catchError(error => { console.error('Qidiruvda xatolik:', error); return of([]); // Xatolik yuzaga kelganda bo'sh massiv qaytaring }) ); }) ); searchObservable.subscribe(results => { console.log('Qidiruv natijalari:', results); // Foydalanuvchi interfeysini qidiruv natijalari bilan yangilang }); function searchAPI(searchTerm: string) { // API so'rovini simulyatsiya qiling return of([`Natija ${searchTerm} 1`, `Natija ${searchTerm} 2`]); } ```
RxJS ning Amaliy Qo'llanmalari
RxJS keng ko'lamli ilovalarda ishlatilishi mumkin bo'lgan ko'p qirrali kutubxonadir. Mana bir nechta keng tarqalgan foydalanish holatlari:
- Foydalanuvchi Kiritishlarini Boshqarish: RxJS klaviatura bosishlari, sichqoncha bosishlari va forma yuborish kabi foydalanuvchi kiritish hodisalarini boshqarish uchun ishlatilishi mumkin.
debounceTime()
vathrottleTime()
kabi operatorlar ish faoliyatini optimallashtirish va ortiqcha so'rovlarning oldini olish uchun ishlatilishi mumkin. - Asinxron Operatsiyalarni Boshqarish: RxJS tarmoq so'rovlari va taymerlar kabi asinxron operatsiyalarni boshqarishning kuchli usulini taqdim etadi.
switchMap()
vamergeMap()
kabi operatorlar bir vaqtda bajariladigan so'rovlarni boshqarish va kutilayotgan so'rovlarni bekor qilish uchun ishlatilishi mumkin. - Real Vaqtdagi Ilovalarni Yaratish: RxJS chat ilovalari va boshqaruv panellari kabi real vaqtdagi ilovalarni yaratish uchun juda mos keladi. Observables WebSockets yoki Server-Sent Events (SSE) dan keladigan ma'lumotlar oqimlarini ifodalash uchun ishlatilishi mumkin.
- Holatni Boshqarish: RxJS Angular, React va Vue.js kabi freymvorklarda holatni boshqarish yechimi sifatida ishlatilishi mumkin. Observables ilova holatini ifodalash uchun, operatorlar esa foydalanuvchi harakatlari yoki hodisalariga javoban holatni o'zgartirish va yangilash uchun ishlatilishi mumkin.
Mashhur Freymvorklar bilan RxJS
Angular:
Angular asinxron operatsiyalarni boshqarish va ma'lumotlar oqimlarini boshqarish uchun RxJS ga qattiq tayanadi. Angular-dagi HttpClient
xizmati Observables qaytaradi va RxJS operatorlari API so'rovlaridan qaytarilgan ma'lumotlarni o'zgartirish va filtrlash uchun keng qo'llaniladi. Angular-ning o'zgarishlarni aniqlash mexanizmi ham ma'lumotlar o'zgarishlariga javoban foydalanuvchi interfeysini samarali yangilash uchun RxJS dan foydalanadi.
Misol: Angular HttpClient bilan RxJS dan foydalanish
```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:
React-da RxJS uchun o'rnatilgan qo'llab-quvvatlash bo'lmasa-da, uni rxjs-hooks
yoki use-rx
kabi kutubxonalar yordamida osongina integratsiya qilish mumkin. Ushbu kutubxonalar React komponentlari ichida Observables ga obuna bo'lish va obunalarni boshqarish imkonini beruvchi maxsus hooklarni taqdim etadi. RxJS React-da asinxron ma'lumotlarni olish, komponent holatini boshqarish va reaktiv foydalanuvchi interfeyslarini yaratish uchun ishlatilishi mumkin.
Misol: React Hooklari bilan RxJS dan foydalanish
```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 (
Sanoq: {count}
Vue.js:
Vue.js ham tabiiy RxJS integratsiyasiga ega emas, lekin uni vue-rx
kabi kutubxonalar bilan yoki Vue komponentlari ichida obunalarni qo'lda boshqarish orqali ishlatish mumkin. RxJS Vue.js da React-dagidek maqsadlarda, masalan, asinxron ma'lumotlarni olish va komponent holatini boshqarish uchun ishlatilishi mumkin.
RxJS dan foydalanish bo'yicha eng yaxshi amaliyotlar
- Observables dan obunani bekor qiling: Xotira sizib chiqishining oldini olish uchun endi kerak bo'lmaganda har doim Observables dan obunani bekor qiling. Obunani bekor qilish uchun
subscribe()
metodi tomonidan qaytarilgan Subscription obyektidan foydalaning. pipe()
metodidan foydalaning: Operatorlarni o'qilishi oson va qo'llab-quvvatlanadigan tarzda zanjir qilib bog'lash uchunpipe()
metodidan foydalaning.- Xatoliklarni ehtiyotkorlik bilan boshqaring: Xatoliklarni boshqarish va ularning Observable zanjiri bo'ylab tarqalishining oldini olish uchun
catchError()
operatoridan foydalaning. - To'g'ri operatorlarni tanlang: O'zingizning aniq holatingiz uchun mos operatorlarni tanlang. RxJS juda ko'p operatorlarni taqdim etadi, shuning uchun ularning maqsadi va xatti-harakatlarini tushunish muhimdir.
- Observables ni oddiy saqlang: Haddan tashqari murakkab Observables yaratishdan saqlaning. Murakkab operatsiyalarni kichikroq, boshqarilishi osonroq Observables ga bo'ling.
Ilg'or RxJS Konsepsiyalari
Subjects:
Subjects ham Observable, ham Observer sifatida ishlaydi. Ular ma'lumotlarni bir nechta obunachiga ko'p yo'nalishli uzatish va oqimga ma'lumotlarni yuborish imkonini beradi. Subjects ning turli xil turlari mavjud, jumladan:
- Subject: Barcha obunachilarga qiymatlarni ko'p yo'nalishli uzatadigan asosiy Subject.
- BehaviorSubject: Boshlang'ich qiymatni talab qiladi va yangi obunachilarga joriy qiymatni chiqaradi.
- ReplaySubject: Belgilangan miqdordagi qiymatlarni buferlaydi va ularni yangi obunachilarga qayta ijro etadi.
- AsyncSubject: Observable tugallanganda faqat oxirgi qiymatni chiqaradi.
Schedulers:
Schedulers Observables ning bir vaqtda ishlashini nazorat qiladi. Ular sizga kodni sinxron yoki asinxron, turli xil oqimlarda yoki ma'lum bir kechikish bilan bajarish imkonini beradi. RxJS bir nechta o'rnatilgan schedulerni taqdim etadi, jumladan:
queueScheduler
: Vazifalarni joriy JavaScript oqimida, joriy ijro kontekstidan so'ng bajarish uchun rejalashtiradi.asapScheduler
: Vazifalarni joriy JavaScript oqimida, joriy ijro kontekstidan so'ng imkon qadar tezroq bajarish uchun rejalashtiradi.asyncScheduler
: VazifalarnisetTimeout
yokisetInterval
yordamida asinxron bajarish uchun rejalashtiradi.animationFrameScheduler
: Vazifalarni keyingi animatsiya kadrida bajarish uchun rejalashtiradi.
Xulosa
RxJS JavaScript-da reaktiv ilovalar yaratish uchun kuchli kutubxonadir. Observables, operatorlar va umumiy patternlarni o'zlashtirish orqali siz yanada sezgir, kengaytiriladigan va qo'llab-quvvatlanadigan ilovalar yaratishingiz mumkin. Angular, React, Vue.js yoki oddiy JavaScript bilan ishlayapsizmi, RxJS asinxron ma'lumotlar oqimlarini boshqarish va murakkab foydalanuvchi interfeyslarini yaratish qobiliyatingizni sezilarli darajada yaxshilaydi.
RxJS bilan reaktiv dasturlash kuchini qabul qiling va JavaScript ilovalaringiz uchun yangi imkoniyatlarni oching!