RxJS (Reactive Extensions for JavaScript) একটি শক্তিশালী লাইব্রেরি যা অ্যাসিঙ্ক্রোনাস ডেটা স্ট্রিম এবং ইভেন্ট-ভিত্তিক প্রোগ্রামিং সহজ এবং কার্যকরী করে তোলে। ডাইনামিক ডেটা স্ট্রিম (যেমন, রিয়েল-টাইম ডেটা, ইউজার ইনপুট, সার্ভার থেকে আসা ডেটা) এর প্রক্রিয়া ও নিয়ন্ত্রণে অনেক সময় বিশেষ অপারেটরের প্রয়োজন হয়, যাতে স্ট্রিমের উপরে আরও উন্নত এবং কার্যকরী কাজ করা যায়।
এখানে কিছু Advanced Operators সম্পর্কে আলোচনা করা হবে, যা ডাইনামিক ডেটা স্ট্রিম ম্যানিপুলেশন এবং কার্যকরী ফিল্টারিং ও ট্রান্সফরমেশন করার জন্য ব্যবহৃত হয়।
1. switchMap()
switchMap() অপারেটরটি একটি নতুন observable তৈরি করে এবং পুরনো observable কে বাতিল (unsubscribe) করে। এটি সাধারণত ব্যবহার করা হয় যখন আপনি নতুন মান প্রাপ্তির জন্য পুরনো স্ট্রিমের পরিবর্তে নতুন স্ট্রিম চান।
বৈশিষ্ট্য:
- এটি নতুন Observable এ সুইচ করে, পুরনো Observable কে বাতিল করে দেয়।
- এটি সাধারণত API কলের মত ফিচারগুলির জন্য ব্যবহৃত হয়, যেখানে প্রতিটি নতুন কল পূর্ববর্তী কলকে বাতিল করতে হবে।
উদাহরণ:
import { of } from 'rxjs';
import { switchMap } from 'rxjs/operators';
const observable = of('a', 'b', 'c').pipe(
switchMap(value => {
return of(value.toUpperCase());
})
);
observable.subscribe(result => console.log(result));
আউটপুট:
A
B
C
এখানে, switchMap() অপারেটরটি নতুন Observable তৈরি করছে এবং প্রতিটি মান প্রাপ্তির জন্য পুরনো মান বাতিল করে।
2. concatMap()
concatMap() অপারেটরটি আসলে map() অপারেটরের মতোই কাজ করে, তবে এটি Observable গুলিকে একত্রে যুক্ত করে এবং স্ট্রিমের উপর sequentially (সিরিয়ালি) অপারেশন চালায়। এটি খুবই উপকারী যখন আপনি চাইছেন একের পর এক কার্যক্রম সম্পন্ন হোক, এবং একটি স্ট্রিম সম্পন্ন না হওয়া পর্যন্ত অন্য স্ট্রিম শুরু না হয়।
বৈশিষ্ট্য:
- স্ট্রিমগুলোকে সিকোয়েন্সিয়ালি (serially) এক্সিকিউট করতে সহায়তা করে।
- পরবর্তী স্ট্রিম এক্সিকিউট হওয়ার আগে পূর্ববর্তী স্ট্রিমের সম্পন্ন হওয়া দরকার।
উদাহরণ:
import { of } from 'rxjs';
import { concatMap } from 'rxjs/operators';
const observable = of(1, 2, 3).pipe(
concatMap(value => of(value * 2))
);
observable.subscribe(result => console.log(result));
আউটপুট:
2
4
6
এখানে, concatMap() অপারেটরটি একের পর এক স্ট্রিমের মান নিয়ে কাজ করছে এবং সিকোয়েন্সিয়ালি তাদের প্রসেস করছে।
3. mergeMap()
mergeMap() অপারেটরটি একাধিক স্ট্রিমকে একযোগে প্রসেস করার জন্য ব্যবহৃত হয়। এটি বিভিন্ন Observable এর মানগুলোকে একত্রে সাবস্ক্রাইব করে এবং একযোগে (concurrently) ফলাফল পাঠায়।
বৈশিষ্ট্য:
- একাধিক Observable কে একযোগে (concurrently) প্রসেস করে।
- যখন আপনি অনেক স্ট্রিম একসাথে প্রসেস করতে চান, এটি উপকারী।
উদাহরণ:
import { of } from 'rxjs';
import { mergeMap } from 'rxjs/operators';
const observable = of(1, 2, 3).pipe(
mergeMap(value => of(value * 10))
);
observable.subscribe(result => console.log(result));
আউটপুট:
10
20
30
এখানে, mergeMap() অপারেটরটি প্রতিটি মানকে একযোগে প্রসেস করছে, এবং একই সময়ে একাধিক স্ট্রিমে কাজ চলছে।
4. debounceTime()
debounceTime() অপারেটরটি মূলত UI-ভিত্তিক অ্যাপ্লিকেশনে ব্যবহার হয় যেখানে একটি ইউজার দ্রুত ইনপুট বা ইভেন্ট তৈরি করে, এবং আপনি শুধু শেষ মান গ্রহণ করতে চান, যাতে অতিরিক্ত বা অপ্রয়োজনীয় রিকোয়েস্টগুলি এড়ানো যায়। এটি আসলে টাইমিং ভিত্তিক debouncing করতে ব্যবহৃত হয়।
বৈশিষ্ট্য:
- একটি নির্দিষ্ট সময়ের মধ্যে নতুন ইনপুট বা পরিবর্তনগুলো মাপা হয় এবং শেষ মানটি রাখা হয়।
- এটি ইভেন্টের চাপ কমাতে এবং শুধুমাত্র প্রয়োজনীয় মান গ্রহণ করতে ব্যবহৃত হয়।
উদাহরণ:
import { fromEvent } from 'rxjs';
import { debounceTime, map } from 'rxjs/operators';
const input = document.getElementById('search');
fromEvent(input, 'input').pipe(
debounceTime(500), // 500 মিলিসেকেন্ড পর ইনপুট নেবে
map(event => event.target.value)
).subscribe(value => console.log(value));
এখানে, debounceTime(500) ব্যবহার করা হয়েছে, যাতে ইনপুটের জন্য ৫০০ মিলিসেকেন্ড বিলম্ব করা হয় এবং ইউজারের ইনপুট কমিয়ে আনা হয়।
5. distinctUntilChanged()
distinctUntilChanged() অপারেটরটি আগের মানের সাথে মিলিয়ে দেখার মাধ্যমে ডুপ্লিকেট মান ফিল্টার করে। এটি এমন অবস্থায় কার্যকর যেখানে আপনি চান না যে একাধিকবার একই মান স্ট্রিমে আসুক।
বৈশিষ্ট্য:
- পূর্ববর্তী মানের সঙ্গে তুলনা করে শুধুমাত্র distinct মান গ্রহণ করা হয়।
- এটি স্ট্রিমে ডুপ্লিকেট মান ফিল্টার করে।
উদাহরণ:
import { of } from 'rxjs';
import { distinctUntilChanged } from 'rxjs/operators';
const observable = of(1, 1, 2, 2, 3, 3, 4);
observable.pipe(
distinctUntilChanged()
).subscribe(value => console.log(value));
আউটপুট:
1
2
3
4
এখানে, distinctUntilChanged() অপারেটরটি পরপর একই মানগুলো ফিল্টার করে ফেলেছে এবং শুধুমাত্র ভিন্ন মানগুলো সাবস্ক্রাইবারে পাঠিয়েছে।
6. combineLatest()
combineLatest() অপারেটরটি একাধিক Observable থেকে সর্বশেষ মানগুলো একত্রিত করে একটি নতুন Observable তৈরি করে। এটি একাধিক স্ট্রিমের সর্বশেষ মান নিয়ে একটি নতুন স্ট্রিম তৈরি করে এবং সাবস্ক্রাইবারে পাঠায়।
বৈশিষ্ট্য:
- একাধিক Observable এর সর্বশেষ মান একত্রিত করে একটি নতুন Observable তৈরি করে।
- এটি সবগুলো Observable এর সর্বশেষ মান গুলি সাবস্ক্রাইবে পাঠাবে।
উদাহরণ:
import { combineLatest, of } from 'rxjs';
const observable1 = of(1, 2, 3);
const observable2 = of('a', 'b', 'c');
combineLatest([observable1, observable2]).subscribe(([val1, val2]) => {
console.log(`Combined values: ${val1}, ${val2}`);
});
আউটপুট:
Combined values: 3, c
এখানে, combineLatest() দুটি Observable এর সর্বশেষ মান একত্রিত করে পাঠাচ্ছে।
7. bufferTime()
bufferTime() অপারেটরটি একটি টাইমার ভিত্তিক buffering কৌশল প্রয়োগ করে, যেখানে আপনি নির্দিষ্ট সময়সীমার মধ্যে আসা ইভেন্টগুলিকে গ্রুপ করে একটি অ্যারে তৈরি করেন। এটি সাধারনত যখন অনেকগুলো ইভেন্ট একসাথে আসছে, তখন ব্যবহৃত হয়।
বৈশিষ্ট্য:
- নির্দিষ্ট সময়সীমার মধ্যে ইভেন্টগুলোকে গ্রুপ করে একটি অ্যারে তৈরি করে।
উদাহরণ:
import { fromEvent } from 'rxjs';
import { bufferTime } from 'rxjs/operators';
const clickStream = fromEvent(document, 'click');
clickStream.pipe(
bufferTime(2000) // Collect clicks in batches of 2 seconds
).subscribe(events => {
console.log('Collected events:', events);
});
এখানে, bufferTime(2000) ব্যবহার করে, ক্লিক ইভেন্টগুলোকে ২ সেকেন্ডের জন্য গ্রুপ করা হচ্ছে।
সারাংশ
RxJS এর Advanced Operators ডাইনামিক ডেটা স্ট্রিমগুলোর প্রক্রিয়াকরণ এবং ম্যানিপুলেশন করতে অত্যন্ত কার্যকরী। এর মাধ্যমে আপনি ডেটার ফিল্টারিং, ট্রান্সফরমেশন, এবং একাধিক স্ট্রিমের মধ্যে সম্পর্ক স্থাপন করতে পারবেন।
- switchMap(): একটি নতুন স্ট্রিমে সুইচ করে পুরনো স্ট্রিমকে বাতিল করে।
- concatMap(): স্ট্রিমগুলোকে সিকোয়েন্সিয়ালি প্রসেস করে।
- mergeMap(): একাধিক স্ট্রিমকে একযোগে প্রসেস করে।
- debounceTime(): অতিরিক্ত ইভেন্ট থেকে পারফরম্যান্স অপটিমাইজ করে।
- distinctUntilChanged(): ডুপ্লিকেট মান ফিল্টার করে।
- combineLatest(): একাধিক স্ট্রিমের সর্বশেষ মান একত্রিত করে।
- bufferTime(): নির্দিষ্ট সময়ে ইভেন্টগুলোকে গ্রুপ করে।
এই অপারেটরগুলো ব্যবহার করে আপনি RxJS এর সাহায্যে আরো দক্ষ এবং কার্যকরী ডেটা স্ট্রিম ম্যানেজমেন্ট করতে পারেন।
Read more