Transformation Operators

আরএক্সজেএস (RxJS) - Web Development

236

Transformation Operators হল RxJS-এর এমন অপারেটরস, যা Observables এর ডেটা স্ট্রিমকে ট্রান্সফর্ম বা পরিবর্তন করে। এই অপারেটরগুলোর মাধ্যমে আপনি ডেটার উপর বিভিন্ন ধরনের কার্যকরী অপারেশন যেমন ফিল্টারিং, ম্যাপিং, অথবা একাধিক স্ট্রিমের সাথে কাজ করতে পারেন।

RxJS-এ Transformation Operators ব্যবহার করার মাধ্যমে আপনি ডেটাকে একটি নির্দিষ্ট ফর্ম্যাটে রূপান্তর করতে পারেন, যা ডেটার পরবর্তী প্রক্রিয়ায় কাজে লাগে। এই অপারেটরগুলো মূলত pipe মেথডের মাধ্যমে চেইন করা হয় এবং প্রতিটি অপারেটর নতুন Observable তৈরি করে।


কিছু সাধারণ Transformation Operators

  1. map()

    map() অপারেটরটি একটি Observable থেকে আসা মানকে নির্দিষ্ট একটি ফাংশনের মাধ্যমে ট্রান্সফর্ম (রূপান্তর) করতে ব্যবহার হয়। এটি অ্যাসিঙ্ক্রোনাস অপারেশনগুলোকে পরিবর্তন বা ফরম্যাট করার জন্য কার্যকরী।

    উদাহরণ:

    import { of } from 'rxjs';
    import { map } from 'rxjs/operators';
    
    const observable = of(1, 2, 3);
    observable.pipe(
      map(x => x * 10)
    ).subscribe(console.log);  // Output: 10, 20, 30
    

    এখানে, map() অপারেটরটি প্রতিটি মানকে ১০ গুণ করে।

  2. mergeMap()

    mergeMap() অপারেটরটি একটি নতুন Observable তৈরি করে এবং এটি বিদ্যমান Observable-এর প্রতিটি মানের জন্য একটি নতুন Observable উৎপন্ন করতে ব্যবহৃত হয়। এটি সব Observable-কে একত্রিত (merge) করে এবং সবগুলো স্ট্রিমের আউটপুট একসাথে সাবস্ক্রাইবারের কাছে পাঠায়।

    উদাহরণ:

    import { of } from 'rxjs';
    import { mergeMap } from 'rxjs/operators';
    
    const observable = of(1, 2, 3);
    observable.pipe(
      mergeMap(x => of(x * 10))  // Mapping each value to a new Observable
    ).subscribe(console.log);  // Output: 10, 20, 30
    

    এখানে, mergeMap() প্রতিটি মানকে একটি নতুন Observable তৈরি করার জন্য ব্যবহার করা হয়েছে, যা পরে সবগুলো মিশিয়ে একত্রিত হবে।

  3. concatMap()

    concatMap() অপারেটরটি mergeMap() এর মতো, তবে এটি নতুন Observable তৈরি করে কিন্তু পূর্ববর্তী Observable সম্পূর্ণ না হওয়া পর্যন্ত পরবর্তী Observable শুরু করবে না। এটি মূলত অ্যাসিঙ্ক্রোনাস অপারেশনগুলিকে সিরিয়ালভাবে (sequentially) এক্সিকিউট করতে ব্যবহৃত হয়।

    উদাহরণ:

    import { of } from 'rxjs';
    import { concatMap } from 'rxjs/operators';
    
    const observable = of(1, 2, 3);
    observable.pipe(
      concatMap(x => of(x * 10))
    ).subscribe(console.log);  // Output: 10, 20, 30
    

    এখানে, concatMap() প্রথম Observable সম্পূর্ণ না হওয়া পর্যন্ত পরবর্তী Observable শুরু করবে না।

  4. switchMap()

    switchMap() অপারেটরটি একটি নতুন Observable তৈরি করে, তবে এটি আগের Observable কে সম্পূর্ণভাবে বাতিল (unsubscribe) করে এবং নতুন Observable-এর সাথে কাজ শুরু করে। এটি তখন ব্যবহার হয় যখন আপনি একটি অ্যাসিঙ্ক্রোনাস অপারেশন বাতিল করে নতুন অপারেশন শুরু করতে চান।

    উদাহরণ:

    import { of } from 'rxjs';
    import { switchMap } from 'rxjs/operators';
    
    const observable = of(1, 2, 3);
    observable.pipe(
      switchMap(x => of(x * 10))
    ).subscribe(console.log);  // Output: 10, 20, 30
    

    এখানে, switchMap() প্রত্যেকটি মানের জন্য একটি নতুন Observable তৈরি করে এবং আগের Observable বাতিল করে নতুনটি সাবস্ক্রাইব করে।

  5. pluck()

    pluck() অপারেটরটি এক্সট্র্যাক্ট করতে ব্যবহার করা হয় যখন আপনার একটি অবজেক্টের মধ্যে নির্দিষ্ট প্রপার্টি প্রয়োজন। এটি মূলত একটি অবজেক্টের কন্টেন্ট থেকে একটি নির্দিষ্ট প্রপার্টি রিটার্ন করে।

    উদাহরণ:

    import { of } from 'rxjs';
    import { pluck } from 'rxjs/operators';
    
    const users = [
      { name: 'John', age: 25 },
      { name: 'Jane', age: 30 }
    ];
    
    of(...users).pipe(
      pluck('name')
    ).subscribe(console.log);  // Output: John, Jane
    

    এখানে, pluck() অপারেটরটি name প্রপার্টি এক্সট্র্যাক্ট করে এবং সাবস্ক্রাইবারকে সেই মানগুলি প্রদান করে।


Transformation Operators এর ব্যবহার

Transformation Operators মূলত অ্যাসিঙ্ক্রোনাস ডেটা বা ইভেন্টের স্ট্রিমে বিভিন্ন ধরনের পরিবর্তন, ট্রান্সফরমেশন বা ফিল্টারিং করতে ব্যবহৃত হয়। এগুলি যখন pipe() মেথডের মধ্যে চেইন করা হয়, তখন আপনি সহজেই একটি স্ট্রিমকে বিভিন্ন ধাপে ট্রান্সফর্ম করতে পারেন।

Pipeable Operations এর মাধ্যমে আপনি নিচের কাজগুলো করতে পারেন:

  • ডেটা মানের পরিবর্তন বা গণনা
  • ডেটার ওপর ফিল্টার বা কন্ডিশন যোগ করা
  • একাধিক Observable একত্রিত করা বা ভিন্ন Observable এর মানে প্রক্রিয়া করা

সারাংশ

RxJS এর Transformation Operators অ্যাসিঙ্ক্রোনাস ডেটার উপর কার্যকরীভাবে ট্রান্সফরমেশন বা পরিবর্তন করতে সাহায্য করে। এগুলি যেমন map, mergeMap, switchMap, concatMap ইত্যাদি ডেটার স্ট্রিমকে চেইন করে, সহজ এবং কার্যকরীভাবে ডেটার সাথে কাজ করতে সহায়ক। RxJS-এ এই অপারেটরগুলির মাধ্যমে আপনি যেকোনো ধরনের স্ট্রিমের ডেটাকে নিজের প্রয়োজন অনুযায়ী পরিবর্তন এবং রূপান্তর করতে পারেন।

Content added By

RxJS (Reactive Extensions for JavaScript) একটি শক্তিশালী লাইব্রেরি, যা অ্যাসিঙ্ক্রোনাস এবং ইভেন্ট-ভিত্তিক ডেটা স্ট্রিমগুলির জন্য ব্যবহৃত হয়। এর মধ্যে map() এবং mapTo() দুটি জনপ্রিয় অপারেটর রয়েছে, যেগুলি স্ট্রিমের ডেটার উপর বিভিন্ন ধরনের ট্রান্সফর্মেশন করতে সাহায্য করে। এগুলি দুটি খুবই গুরুত্বপূর্ণ অপারেটর, যা ডেটা স্ট্রিমের মান পরিবর্তন বা ম্যানিপুলেট করতে ব্যবহৃত হয়। নিচে map() এবং mapTo() এর ব্যবহার এবং পার্থক্য ব্যাখ্যা করা হলো।


1. map() অপারেটর

map() অপারেটরটি Functional Programming প্যাটার্ন অনুসরণ করে, যেখানে আপনি প্রতিটি মানের উপর একটি নির্দিষ্ট ফাংশন প্রয়োগ করতে পারেন। এটি মূলত একটি মানকে অন্য মানে রূপান্তর করার জন্য ব্যবহৃত হয়।

ব্যবহার:
map() অপারেটরটি একটি ফাংশন নেয় যা একটি মানকে ট্রান্সফর্ম বা রূপান্তর করে এবং সেই মানকে সাবস্ক্রাইবারদের কাছে পাঠায়। এটি মূল Observable স্ট্রিমের মধ্যে প্রতিটি মানকে ম্যানিপুলেট করার জন্য ব্যবহৃত হয়।

উদাহরণ:

import { of } from 'rxjs';
import { map } from 'rxjs/operators';

const numbers$ = of(1, 2, 3, 4, 5);

numbers$.pipe(
  map(x => x * 10) // Each number is multiplied by 10
).subscribe(result => console.log(result));

আউটপুট:

10
20
30
40
50

এখানে, map() অপারেটরটি numbers$ Observable থেকে প্রাপ্ত প্রতিটি মানকে ১০ গুণ করে পরিবর্তন করেছে।


2. mapTo() অপারেটর

mapTo() অপারেটরটি একটি নির্দিষ্ট মানকে সরাসরি map করে সব সময়। এটি fixed value মেপিং করার জন্য ব্যবহার করা হয়, যেখানে আপনি একাধিক স্ট্রিমের মাধ্যমে প্রাপ্ত ডেটার মানের পরিবর্তে একটি স্থির (static) মান পাঠাতে চান। এটি একটি নির্দিষ্ট মানের জন্য কার্যকরী, যার মানে এটি কোন ইনপুট মানের উপর ভিত্তি না করে একই আউটপুট প্রদান করে।

ব্যবহার:
mapTo() অপারেটরটি একটি নির্দিষ্ট ফিক্সড ভ্যালু নেয় এবং সেটি প্রত্যেকটি স্ট্রিমের জন্য পাঠায়।

উদাহরণ:

import { of } from 'rxjs';
import { mapTo } from 'rxjs/operators';

const source$ = of('A', 'B', 'C', 'D');

source$.pipe(
  mapTo('Z') // Always maps to 'Z'
).subscribe(result => console.log(result));

আউটপুট:

Z
Z
Z
Z

এখানে, mapTo() অপারেটরটি প্রতি ইভেন্টের জন্য Z মানটি প্রেরণ করেছে, যদিও ইনপুট মানগুলি 'A', 'B', 'C', 'D' ছিল।


map() এবং mapTo() এর মধ্যে পার্থক্য

বৈশিষ্ট্যmap()mapTo()
ফাংশনালিটিপ্রত্যেকটি মানের উপর ট্রান্সফর্মেশন বা রূপান্তর প্রয়োগ করে।একটি নির্দিষ্ট বা ফিক্সড মান সরাসরি মাপ করে।
ইনপুট এবং আউটপুটইনপুট মানের উপর ভিত্তি করে আউটপুট তৈরি করে।সব ইনপুট মানের জন্য একই আউটপুট প্রদান করে।
ব্যবহারইনপুট ডেটার প্রক্রিয়াকরণের জন্য ব্যবহার করা হয়।নির্দিষ্ট মান বা সিগন্যাল পাঠানোর জন্য ব্যবহৃত হয়।

সারাংশ

  • map() অপারেটরটি প্রতিটি মানের উপর একটি নির্দিষ্ট ফাংশন প্রয়োগ করে ডেটার মান পরিবর্তন করতে ব্যবহৃত হয়।
  • mapTo() অপারেটরটি সব সময় একটি নির্দিষ্ট, পূর্বনির্ধারিত মান পাঠাতে ব্যবহৃত হয়, যেটি ইনপুট ডেটার উপর নির্ভর করে না।

এই দুটি অপারেটর RxJS স্ট্রিমের ডেটার উপর বিভিন্ন ধরনের ট্রান্সফর্মেশন করার জন্য খুবই কার্যকরী।

Content added By

RxJS (Reactive Extensions for JavaScript) একটি শক্তিশালী লাইব্রেরি যা বিভিন্ন ধরনের অপারেটরের মাধ্যমে ডেটা ম্যানিপুলেশন করতে সহায়ক। এর মধ্যে pluck() এবং scan() অপারেটর দুটি ডেটা স্ট্রিমের উপর কাজ করে এবং তাদের মান পরিবর্তন করতে সাহায্য করে। এই দুটি অপারেটর বিভিন্ন ডেটা ট্রান্সফরমেশন বা অ্যাকমুলেশন (accumulation) করার জন্য ব্যবহৃত হয়।


1. pluck() অপারেটর

pluck() অপারেটরটি মূলত একটি Observable এর অবজেক্ট থেকে একটি নির্দিষ্ট প্রপার্টি (property) বের করার জন্য ব্যবহৃত হয়। এটি কোনো নির্দিষ্ট কীগুলির মানটি আনে এবং তার উপর কাজ করতে সহায়ক। যখন কোনো Observable স্ট্রিম অবজেক্টের একটি প্রপার্টি থেকে একাধিক মান পাঠায়, তখন pluck() ব্যবহার করে আপনি শুধু সেই প্রপার্টির মানটি বের করতে পারেন।

বৈশিষ্ট্য:

  • Object properties extraction: এটি অবজেক্টের নির্দিষ্ট প্রপার্টি বের করতে ব্যবহৃত হয়।
  • Flat output: pluck()-এর আউটপুটটি একটি সাধারণ মান হিসেবে পাওয়া যায়, অবজেক্টের মধ্যে অন্তর্ভুক্ত তথ্য নয়।

উদাহরণ:

import { of } from 'rxjs';
import { pluck } from 'rxjs/operators';

const data = [
  { name: 'John', age: 25 },
  { name: 'Jane', age: 30 },
  { name: 'Mike', age: 35 }
];

of(...data)
  .pipe(
    pluck('name') // 'name' প্রপার্টি থেকে মান বের করা
  )
  .subscribe(name => console.log(name));

// Output:
// John
// Jane
// Mike

এখানে, pluck('name') অপারেটরটি প্রতিটি অবজেক্টের name প্রপার্টি থেকে মান বের করেছে এবং শুধুমাত্র name এর মান আউটপুট করেছে।


2. scan() অপারেটর

scan() অপারেটরটি একটি অ্যাকুমুলেটর বা reducer হিসেবে কাজ করে, যা প্রতিটি ইভেন্ট বা মানের উপর ভিত্তি করে একটি অ্যাকুমুলেটেড ফলাফল তৈরি করে। এটি মূলত accumulation বা cumulative operations এর জন্য ব্যবহৃত হয়, যেমন সংখ্যা যোগ বা গুন করা, একটি অ্যারে তৈরি করা, ইত্যাদি।

scan() অপারেটরটি প্রথমে একটি ইনিশিয়াল মান নেয় এবং তারপর প্রতিটি ইভেন্ট বা মানের উপর কাজ করে। এটি একটি ইনপুট এবং আউটপুট মানের মধ্যে পরিবর্তন ঘটায়, এবং সম্পূর্ণ স্ট্রিমটি সম্পন্ন হওয়ার আগে এটিকে সাবস্ক্রাইবারদের কাছে সরবরাহ করে।

বৈশিষ্ট্য:

  • Accumulative operations: এটি আগের মানের সাথে নতুন মানের যোগফল, গুণফল ইত্যাদি বের করতে সহায়তা করে।
  • Stateful operation: এটি একটি স্টেট ধারণ করে এবং পরবর্তী মানগুলির সাথে সেই স্টেটটি আপডেট করে।

উদাহরণ:

import { of } from 'rxjs';
import { scan } from 'rxjs/operators';

const numbers = [1, 2, 3, 4, 5];

of(...numbers)
  .pipe(
    scan((acc, value) => acc + value, 0) // ইনিশিয়াল মান 0, প্রতিটি মানের সাথে যোগফল করা হচ্ছে
  )
  .subscribe(accumulatedValue => console.log(accumulatedValue));

// Output:
// 1
// 3
// 6
// 10
// 15

এখানে, scan() অপারেটরটি ইনপুট মানের প্রতি নতুন মান যোগ করছে এবং ধীরে ধীরে একটি অ্যাকুমুলেটেড মান তৈরি করছে। প্রতিটি নতুন মানের সাথে আগের মানের যোগফল হিসেবে আউটপুট প্রদর্শিত হয়।


pluck() এবং scan() এর মাধ্যমে ডেটা ম্যানিপুলেশন

pluck() এবং scan() দুটি অপারেটর একসাথে ব্যবহার করে ডেটা স্ট্রিমে অ্যাক্সেস এবং ম্যানিপুলেশন খুবই সহজ হয়ে যায়। pluck() সাধারণত অবজেক্ট থেকে নির্দিষ্ট প্রপার্টি বের করতে ব্যবহৃত হয়, যখন scan() স্টেট বা মানের অ্যাকুমুলেশন করতে সাহায্য করে।

উদাহরণ:

import { of } from 'rxjs';
import { pluck, scan } from 'rxjs/operators';

const data = [
  { id: 1, value: 10 },
  { id: 2, value: 20 },
  { id: 3, value: 30 }
];

of(...data)
  .pipe(
    pluck('value'), // 'value' প্রপার্টি থেকে মান বের করা
    scan((acc, value) => acc + value, 0) // মানগুলো যোগ করা
  )
  .subscribe(accumulatedValue => console.log(accumulatedValue));

// Output:
// 10
// 30
// 60

এখানে, প্রথমে pluck('value') অপারেটরটি অবজেক্টের value প্রপার্টি থেকে মান বের করেছে এবং তারপর scan() অপারেটরটি সেই মানগুলো একত্রিত করে একটি অ্যাকুমুলেটেড ফলাফল তৈরি করেছে।


সারাংশ

  • pluck() অপারেটরটি Observable-এর মধ্যে থাকা অবজেক্ট থেকে নির্দিষ্ট প্রপার্টি বের করে এবং সরল করে দেয়।
  • scan() অপারেটরটি অ্যাকুমুলেটেড বা cumulative মান তৈরি করতে ব্যবহৃত হয়, যা প্রতিটি নতুন মানের সাথে আগের মান যোগফল বা অন্য কোনো অপারেশন করতে সহায়তা করে।

এই অপারেটরগুলোর মাধ্যমে আপনি আপনার ডেটা স্ট্রিমকে সহজভাবে ম্যানিপুলেট করতে পারবেন এবং আরো কার্যকরীভাবে ডেটার উপর কাজ করতে পারবেন।

Content added By

RxJS-এ buffer, bufferTime, এবং bufferCount হল তিনটি অপারেটর যা ডেটা স্ট্রিমের মানগুলোকে একটি অ্যারে (array) বা কন্টেইনারে একত্রিত করে রাখে। এই অপারেটরগুলির মাধ্যমে, আপনি স্ট্রিমের ডেটাকে গ্রুপ বা ব্যাচ আকারে ক্যাপচার করতে পারেন, যা একাধিক সাবস্ক্রাইবারের জন্য কার্যকরী হতে পারে। প্রতিটি অপারেটর বিভিন্নভাবে ডেটাকে buffer (ধারণ) করে, এবং তাদের ব্যবহারিক পরিস্থিতি আলাদা।

এই অপারেটরগুলির মাধ্যমে আপনি একটি Observable-এর মানগুলি একটি নির্দিষ্ট সময়ের জন্য বা নির্দিষ্ট সংখ্যা পর্যন্ত একত্রিত করতে পারেন, এবং পরবর্তীতে সেই গ্রুপ বা ব্যাচে ডেটা প্রদান করতে পারেন।


1. buffer()

buffer() অপারেটরটি একটি Observable এর মানগুলোকে একটি অ্যারেতে গ্রুপ করে এবং একটি নির্দিষ্ট trigger Observable-কে সাবস্ক্রাইব করার পর সেই অ্যারে পাঠায়। Trigger Observable সাধারণত অন্য কোন ইভেন্ট বা স্ট্রিম হতে পারে, যেমন একটি click ইভেন্ট বা একটি নির্দিষ্ট সময়কাল।

বৈশিষ্ট্য:

  • Trigger Observable: এটি একটি trigger Observable ব্যবহার করে, যা যখনই একটি নির্দিষ্ট মান পায়, তখন buffer হওয়া সমস্ত মান একটি অ্যারেতে প্রেরণ করে।

উদাহরণ:

import { interval } from 'rxjs';
import { buffer } from 'rxjs/operators';

const source = interval(1000); // প্রতি সেকেন্ডে একটি সংখ্যা পাঠাবে
const trigger = interval(3000); // প্রতি ৩ সেকেন্ডে trigger হবে

source.pipe(
  buffer(trigger)
).subscribe(val => {
  console.log('Buffered values:', val);
});

এখানে, source প্রতি সেকেন্ডে একটি সংখ্যা পাঠাবে, কিন্তু trigger প্রতি ৩ সেকেন্ডে নতুন মান আসবে। ফলে, ৩ সেকেন্ড পর source এর তিনটি মান একটি অ্যারেতে (buffer) গ্রুপ হয়ে সাবস্ক্রাইবারকে পাঠানো হবে।

আউটপুট:

Buffered values: [0, 1, 2]
Buffered values: [3, 4, 5]
Buffered values: [6, 7, 8]

2. bufferTime()

bufferTime() অপারেটরটি একটি Observable থেকে আসা মানগুলোকে একটি নির্দিষ্ট সময়কাল (time window) ধরে একটি অ্যারেতে গ্রুপ করে। এটি সময়ভিত্তিক buffering সম্পাদন করে, যেখানে একবার একটি নির্দিষ্ট সময়সীমা পূর্ণ হলে, তখনো যতগুলো মান পাওয়া গেছে, সেগুলিকে একটি অ্যারেতে পুশ করা হয় এবং নতুন buffer শুরু হয়।

বৈশিষ্ট্য:

  • Time Window: আপনি একটি সময়কাল (in milliseconds) নির্ধারণ করতে পারেন, যার মধ্যে ডেটা অ্যারে হিসেবে গ্রুপ হবে।
  • Automatic Buffer: নির্দিষ্ট সময় পর নতুন buffer তৈরি হয় এবং পুরনো buffer সাবস্ক্রাইবারকে পাঠানো হয়।

উদাহরণ:

import { interval } from 'rxjs';
import { bufferTime } from 'rxjs/operators';

const source = interval(1000); // প্রতি সেকেন্ডে একটি সংখ্যা পাঠাবে

source.pipe(
  bufferTime(3000) // প্রতি ৩ সেকেন্ডে buffer হবে
).subscribe(val => {
  console.log('Buffered values:', val);
});

এখানে, bufferTime(3000) মানে প্রতি ৩ সেকেন্ড পর সেগুলির একটি অ্যারে তৈরি হবে এবং সাবস্ক্রাইবারকে পাঠানো হবে।

আউটপুট:

Buffered values: [0, 1, 2]
Buffered values: [3, 4, 5]
Buffered values: [6, 7, 8]

3. bufferCount()

bufferCount() অপারেটরটি একটি Observable থেকে আসা মানগুলোর একটি নির্দিষ্ট সংখ্যা পর্যন্ত গ্রুপ করে এবং সেই গ্রুপকে একটি অ্যারেতে পাঠায়। যখন সেই নির্দিষ্ট সংখ্যা পূর্ণ হবে, তখন একটি অ্যারে সাবস্ক্রাইবারকে পাঠানো হয় এবং একটি নতুন অ্যারে শুরু হয়।

বৈশিষ্ট্য:

  • Count: আপনি কতটি মান একত্রিত করতে চান তা নির্ধারণ করেন (যেমন প্রতি ৫টি মানে একত্রিত হবে)।
  • Automatic Buffer: যখন নির্দিষ্ট মানের সংখ্যা পূর্ণ হয়, তখন buffer পাঠানো হয় এবং নতুন buffer তৈরি হয়।

উদাহরণ:

import { interval } from 'rxjs';
import { bufferCount } from 'rxjs/operators';

const source = interval(1000); // প্রতি সেকেন্ডে একটি সংখ্যা পাঠাবে

source.pipe(
  bufferCount(3) // প্রতি ৩টি মানে buffer হবে
).subscribe(val => {
  console.log('Buffered values:', val);
});

এখানে, bufferCount(3) মানে প্রতি ৩টি মানে একটি অ্যারে তৈরি হবে এবং সেটি সাবস্ক্রাইবারকে পাঠানো হবে।

আউটপুট:

Buffered values: [0, 1, 2]
Buffered values: [3, 4, 5]
Buffered values: [6, 7, 8]

সারাংশ

  • buffer(): Trigger Observable এর মাধ্যমে ডেটাকে গ্রুপ করে এবং trigger হওয়ার পর সেই মানগুলো একটি অ্যারেতে পাঠায়।
  • bufferTime(): নির্দিষ্ট সময় (time window) অনুযায়ী ডেটা গ্রুপ করে এবং সময় পরপর অ্যারে হিসেবে পাঠায়।
  • bufferCount(): একটি নির্দিষ্ট সংখ্যা পর্যন্ত ডেটা গ্রুপ করে এবং সেই সংখ্যাটি পূর্ণ হওয়ার পর অ্যারে হিসেবে পাঠায়।

এই তিনটি অপারেটর আপনাকে buffering এবং batching এর জন্য বিভিন্ন পদ্ধতি প্রদান করে, যাতে আপনি RxJS স্ট্রিমগুলোকে আরো কার্যকরীভাবে এবং নির্দিষ্ট শর্তে পরিচালনা করতে পারেন।

Content added By

RxJS-এ transformation operators ডেটার স্ট্রিমকে একটি নির্দিষ্ট রূপে পরিবর্তন করতে ব্যবহৃত হয়। এর মধ্যে switchMap(), concatMap(), এবং mergeMap() হল তিনটি গুরুত্বপূর্ণ অপারেটর, যেগুলি অ্যাসিঙ্ক্রোনাস অপারেশন এবং স্ট্রিমের সাথে কাজ করার সময় আপনাকে সুবিধা প্রদান করে। এই অপারেটরগুলো বিশেষভাবে গুরুত্বপূর্ণ যখন আপনার কাছে একাধিক Observable এবং অ্যাসিঙ্ক্রোনাস কার্যক্রম থাকে এবং আপনি তাদের সাথে একটি নির্দিষ্ট কৌশলে কাজ করতে চান।

এই অপারেটরগুলোর মধ্যে প্রধান পার্থক্য হচ্ছে কিভাবে তারা আগের স্ট্রিমের সাথে নতুন স্ট্রিমগুলিকে ম্যানেজ করে এবং কিভাবে তারা সাবস্ক্রাইবারদের কাছে ডেটা প্রেরণ করে।


1. switchMap()

switchMap() একটি ট্রান্সফরমেশন অপারেটর যা প্রতিটি ইনপুট ভ্যালুর জন্য একটি নতুন Observable তৈরি করে এবং পুরনো Observable-এর সাবস্ক্রিপশন বন্ধ করে দেয়। এটি সাধারণত ব্যবহৃত হয় যখন আপনি নতুন সাবস্ক্রিপশন তৈরি করতে চান এবং আগেরটি বাতিল করতে চান। এটি বিশেষভাবে ব্যবহারী যখন আপনি অ্যাসিঙ্ক্রোনাস ইভেন্ট বা API কল ইত্যাদি পরিচালনা করছেন এবং পুরনো কলগুলি আর প্রয়োজন নেই।

বৈশিষ্ট্য:

  • প্রতিটি ইনপুট ভ্যালুর জন্য একটি নতুন Observable তৈরি করে।
  • আগের Observable-এর সাবস্ক্রিপশন বন্ধ করে দেয়।
  • এটি পূর্ববর্তী ডেটা স্ট্রিম-এর উপর নতুন স্ট্রিমের কাজকে অগ্রাধিকার দেয়।

উদাহরণ:

import { of } from 'rxjs';
import { switchMap } from 'rxjs/operators';

const source$ = of('A', 'B', 'C');

source$.pipe(
  switchMap(val => {
    console.log('Switching to new Observable with value:', val);
    return of(val + '1', val + '2');  // A new observable for each input
  })
).subscribe(result => console.log(result));

// Output:
// Switching to new Observable with value: A
// A1
// A2
// Switching to new Observable with value: B
// B1
// B2
// Switching to new Observable with value: C
// C1
// C2

এখানে, যখন একটি নতুন মান আসছে, আগের মানের Observable বাতিল হয়ে নতুন Observable সাবস্ক্রাইব করা হচ্ছে।


2. concatMap()

concatMap() একটি ট্রান্সফরমেশন অপারেটর যা প্রতি ইনপুট ভ্যালুতে একটি নতুন Observable তৈরি করে, এবং প্রত্যেকটি Observable সাবস্ক্রাইব করার জন্য একে একে আসতে থাকে। এটি নিশ্চিত করে যে আগের Observable শেষ না হওয়া পর্যন্ত নতুন Observable শুরু হবে না, অর্থাৎ সমস্ত সাবস্ক্রিপশন একটি সিরিয়াল (sequential) অর্ডারে সম্পন্ন হবে।

বৈশিষ্ট্য:

  • প্রতিটি ইনপুট ভ্যালুতে একটি নতুন Observable তৈরি হয়।
  • পূর্ববর্তী Observable সম্পূর্ণ না হওয়া পর্যন্ত নতুন Observable শুরু হয় না।
  • এটি সিরিয়াল প্রক্রিয়া বজায় রাখে, অর্থাৎ সাবস্ক্রাইবারগুলিকে একে একে ডেটা প্রদান করা হয়।

উদাহরণ:

import { of } from 'rxjs';
import { concatMap } from 'rxjs/operators';

const source$ = of('A', 'B', 'C');

source$.pipe(
  concatMap(val => {
    console.log('Processing value:', val);
    return of(val + '1', val + '2');
  })
).subscribe(result => console.log(result));

// Output:
// Processing value: A
// A1
// A2
// Processing value: B
// B1
// B2
// Processing value: C
// C1
// C2

এখানে, concatMap() প্রতিটি মানের জন্য একটি নতুন Observable তৈরি করছে এবং এই Observable গুলো সিরিয়ালি প্রক্রিয়া করছে, অর্থাৎ একটি Observable সম্পূর্ণ না হওয়া পর্যন্ত পরবর্তী Observable শুরু হচ্ছে না।


3. mergeMap()

mergeMap() একটি ট্রান্সফরমেশন অপারেটর যা প্রতি ইনপুট ভ্যালুর জন্য একটি নতুন Observable তৈরি করে, এবং সমস্ত Observable গুলোকে সমান্তরালভাবে (concurrently) সাবস্ক্রাইব করতে দেয়। এটি একটি অসীম বা সীমাহীন সংখ্যক অ্যাসিঙ্ক্রোনাস অপারেশন একসাথে পরিচালনা করতে ব্যবহৃত হয়। তবে, এতে সাবস্ক্রিপশনগুলোর অর্ডার সংরক্ষিত থাকে না, অর্থাৎ ডেটা সবসময় আসতে আসতে থাকে।

বৈশিষ্ট্য:

  • প্রতিটি ইনপুট ভ্যালুর জন্য একটি নতুন Observable তৈরি হয়।
  • সমস্ত Observable গুলো একসাথে (concurrently) সাবস্ক্রাইব হয়।
  • এতে অর্ডার সংরক্ষিত থাকে না

উদাহরণ:

import { of } from 'rxjs';
import { mergeMap } from 'rxjs/operators';

const source$ = of('A', 'B', 'C');

source$.pipe(
  mergeMap(val => {
    console.log('Processing value:', val);
    return of(val + '1', val + '2');
  })
).subscribe(result => console.log(result));

// Output:
// Processing value: A
// A1
// A2
// Processing value: B
// B1
// B2
// Processing value: C
// C1
// C2

এখানে, mergeMap() সব Observable গুলোকে একসাথে সাবস্ক্রাইব করে, অর্থাৎ সমস্ত স্ট্রিম একসাথে প্রক্রিয়া হয় এবং কোন নির্দিষ্ট অর্ডার বজায় থাকে না।


পার্থক্য - switchMap(), concatMap(), mergeMap()

বৈশিষ্ট্যswitchMap()concatMap()mergeMap()
স্ট্রিমের আচরণআগের স্ট্রিম বাতিল করে নতুন স্ট্রিম শুরুআগের স্ট্রিম সম্পূর্ণ না হলে নতুন স্ট্রিম শুরু হয় নাসকল স্ট্রিম সমান্তরালভাবে চালানো হয়
স্ট্রিমের অর্ডারনতুন স্ট্রিম সব সময় প্রাধান্য পায়স্ট্রিমগুলির অর্ডার রক্ষা করা হয়স্ট্রিমগুলির অর্ডার রক্ষা করা হয় না
ব্যবহারযখন আগের কাজটি আর প্রয়োজন নেই, নতুন কাজ শুরু করতে হয়যখন কাজগুলো সিরিয়ালভাবে সম্পন্ন করতে হয়যখন একাধিক কাজ একসাথে সম্পন্ন করতে হয়
পরীক্ষাHTTP রিকোয়েস্ট বা একাধিক API কল, যেখানে আগের কল বাতিল করতে হয়ফাইল আপলোড, যেখানে প্রতিটি কাজ শেষে পরবর্তী কাজ শুরু হয়বহু অ্যাসিঙ্ক্রোনাস ইভেন্ট বা কল একসাথে প্রক্রিয়া করতে

সারাংশ

switchMap(), concatMap(), এবং mergeMap() RxJS-এ গুরুত্বপূর্ণ transformation operators, যেগুলি আপনার অ্যাসিঙ্ক্রোনাস স্ট্রিম পরিচালনা করার পদ্ধতি ভিন্নভাবে পরিবর্তন করে।

  • switchMap() ব্যবহার করা হয় যখন আপনি আগের স্ট্রিমটি বাতিল করে নতুন স্ট্রিমকে অগ্রাধিকার দিতে চান।
  • concatMap() ব্যবহার করা হয় যখন আপনি প্রতিটি Observable সাবস্ক্রাইব করার জন্য সিরিয়াল অর্ডার বজায় রাখতে চান।
  • mergeMap() ব্যবহার করা হয় যখন আপনি একাধিক অ্যাসিঙ্ক্রোনাস কাজ সমান্তরালভাবে (concurrently) পরিচালনা করতে চান।

এই অপারেটরগুলো আপনাকে অ্যাসিঙ্ক্রোনাস এবং ইভেন্ট-ভিত্তিক প্রোগ্রামিং এর ক্ষেত্রে আরও শক্তিশালী এবং নমনীয় কোড লেখার সুযোগ দেয়।

Content added By
Promotion

Are you sure to start over?

Loading...