কৌণিক Promise
এবং এর Observable
মধ্যে পার্থক্য কি ?
প্রতিটি ক্ষেত্রে একটি উদাহরণ উভয় ক্ষেত্রে বুঝতে সহায়তা করবে। কোন পরিস্থিতিতে আমরা প্রতিটি কেস ব্যবহার করতে পারি?
কৌণিক Promise
এবং এর Observable
মধ্যে পার্থক্য কি ?
প্রতিটি ক্ষেত্রে একটি উদাহরণ উভয় ক্ষেত্রে বুঝতে সহায়তা করবে। কোন পরিস্থিতিতে আমরা প্রতিটি কেস ব্যবহার করতে পারি?
উত্তর:
প্রতিশ্রুতি
একটি Promise
একটি পরিচালনা একক ঘটনা যখন একটি ASYNC অপারেশন সম্পন্ন হয়ে বা ব্যর্থ।
দ্রষ্টব্য: সেখানে Promise
লাইব্রেরি রয়েছে যা বাতিলকরণ সমর্থন করে, তবে ES6 Promise
এখনও পর্যন্ত হয় না।
লক্ষণীয়
আন Observable
একটি Stream
(অনেক ভাষায়) এর মতো এবং শূন্য বা আরও বেশি ইভেন্টগুলিতে পাস করার অনুমতি দেয় যেখানে প্রতিটি ইভেন্টের জন্য কলব্যাক বলা হয়।
প্রায়শই Observable
বেশি পছন্দ করা হয় Promise
কারণ এটি Promise
আরও অনেক কিছু বৈশিষ্ট্য সরবরাহ করে । আপনি Observable
0, 1 বা একাধিক ইভেন্ট হ্যান্ডেল করতে চান তা বিবেচ্য নয়। আপনি প্রতিটি ক্ষেত্রে একই এপিআই ব্যবহার করতে পারেন।
Observable
এছাড়াও উপর সুবিধা আছে Promise
হতে cancelable । একটি সার্ভার অথবা অন্য কোনো দামী ASYNC অপারেশন একটি HTTP অনুরোধের ফলাফলের আর প্রয়োজন না হয়, তাহলে Subscription
একটি এর Observable
সময়, সদস্যতা বাতিল করতে পারবেন Promise
এমনকি যখন আপনি প্রজ্ঞাপন প্রয়োজন হবে না অবশেষে সাফল্য বা ব্যর্থ কলব্যাক ডাকব বা ফলাফল এটি আর সরবরাহ করে।
লক্ষণীয় প্রদান করে অপারেটরদের মত map
, forEach
, reduce
, ... একটি অ্যারের অনুরূপ
এখানে শক্তিশালী অপারেটরগুলি retry()
বা replay()
, ... যা প্রায়শই বেশ কার্যকর।
Promise
, পাশাপাশি async
/ await
আপনার কোডটিকে আবার সমতল করে তোলে! বেশিরভাগ পরিস্থিতিতে, এবং প্রকল্পগুলিতে যা রকেট বিজ্ঞানের সাথে কাজ করে না, অযথা জটিল পদ্ধতির জটিল চেইনগুলি সহ সেই ভয়ঙ্কর নেস্টেড ফাংশনগুলি লেখার দরকার নেই। আপনি ট্রান্সফারারগুলির সাথে async
/ await
আজকে ব্যবহার করতে পারেন , পছন্দ করতে TypeScript
এবং কোনও rxjs
বয়লারপ্লেট ছাড়াই প্রকৃত মানব-পঠনযোগ্য ফ্ল্যাট কোড লিখতে পারেন । আপনার সম্ভবত এখনও rxjs
নির্বাচিত পরিস্থিতিতে কখনও কখনও প্রয়োজন হবে , কারণ এতে সত্যিকার অর্থে প্রচুর পরিমাণে অফার করা থাকে।
উভয়ই Promises
এবং Observables
আমাদের বিমূর্ততা সরবরাহ করে যা আমাদের অ্যাপ্লিকেশনগুলির অ্যাসিনক্রোনাস প্রকৃতির মোকাবেলায় সহায়তা করে । তাদের মধ্যে পার্থক্যটি পরিষ্কার করা হয়েছে @ জন্টার এবং @ রেলু দ্বারা।
যেহেতু একটি কোড স্নিপেট এক হাজার শব্দের মূল্যবান, তাই এগুলি আরও সহজে বোঝার জন্য নীচের উদাহরণটি দিয়ে যান।
অসাধারণ নিবন্ধের জন্য @ ক্রিসটফ বার্গডর্ফকে ধন্যবাদ
কৌণিক এইচটিটিপি নিয়ে কাজ করার প্রতিশ্রুতির পরিবর্তে আরএক্স.জেস অবজারভেবল ব্যবহার করে।
মনে করুন যে আপনি একটি অনুসন্ধান ফাংশন তৈরি করছেন যা আপনার টাইপ করার সাথে সাথে আপনাকে ফলাফলগুলি প্রদর্শন করবে। পরিচিত মনে হচ্ছে তবে সেই কাজটি নিয়ে প্রচুর চ্যালেঞ্জ রয়েছে।
HTTP
অনুরোধের ঝড় দিয়ে তাদের প্লাবিত করা উচিত । মূলত, ব্যবহারকারীরা প্রতিটি কীস্ট্রোকের পরিবর্তে টাইপ করা বন্ধ করে দিলে আমরা কেবল এটি আঘাত করতে চাই।ডেমোটিতে কেবল দুটি ফাইল থাকে: app.ts
এবং wikipedia-service.ts
। একটি বাস্তব বিশ্বের দৃশ্যে, যদিও আমরা সম্ভবত জিনিসগুলি আরও বিভক্ত করব।
নীচে প্রতিশ্রুতি ভিত্তিক বাস্তবায়ন যা বর্ণিত প্রান্তের কেসগুলির কোনওটিই পরিচালনা করে না।
wikipedia-service.ts
import { Injectable } from '@angular/core';
import { URLSearchParams, Jsonp } from '@angular/http';
@Injectable()
export class WikipediaService {
constructor(private jsonp: Jsonp) {}
search (term: string) {
var search = new URLSearchParams()
search.set('action', 'opensearch');
search.set('search', term);
search.set('format', 'json');
return this.jsonp
.get('http://en.wikipedia.org/w/api.php?callback=JSONP_CALLBACK', { search })
.toPromise()
.then((response) => response.json()[1]);
}
}
প্রদত্ত অনুসন্ধানের শব্দটি দিয়ে আমরা উইকিপিডিয়া এপিআইয়ের বিরুদ্ধে Jsonp
একটি GET
অনুরোধ করার জন্য পরিষেবাটি ইনজেকশন দিচ্ছি । লক্ষ করুন যে, আমরা কল অর্ডারে একটি থেকে পেতে একটি থেকে । শেষ পর্যন্ত আমাদের অনুসন্ধান পদ্ধতির রিটার্ন টাইপ হিসাবে শেষ করুন ।toPromise
Observable<Response>
Promise<Response>
Promise<Array<string>>
app.ts
// check the plnkr for the full list of imports
import {...} from '...';
@Component({
selector: 'my-app',
template: `
<div>
<h2>Wikipedia Search</h2>
<input #term type="text" (keyup)="search(term.value)">
<ul>
<li *ngFor="let item of items">{{item}}</li>
</ul>
</div>
`
})
export class AppComponent {
items: Array<string>;
constructor(private wikipediaService: WikipediaService) {}
search(term) {
this.wikipediaService.search(term)
.then(items => this.items = items);
}
}
এখানে খুব একটা আশ্চর্যের কিছু নেই। আমরা আমাদের ইনজেক্ট করি WikipediaService
এবং এটির কার্যকারিতাটি অনুসন্ধান পদ্ধতির মাধ্যমে টেমপ্লেটে প্রকাশ করি। টেমপ্লেটটি কেবল কীআপ এবং কলগুলিতে আবদ্ধ হয় search(term.value)
।
আমরা উইকিপিডিয়া সার্ভিসের অনুসন্ধান পদ্ধতিটি প্রত্যাবর্তনের প্রতিশ্রুতিটির ফলাফলটি আনল্যাপ্ট করি এবং এটি টেমপ্লেটে একটি সরল সারণী হিসাবে প্রকাশ করি যাতে আমরা *ngFor
এটির মধ্য দিয়ে লুপ পেতে পারি এবং আমাদের জন্য একটি তালিকা তৈরি করতে পারি।
প্লামকারে প্রতিশ্রুতি ভিত্তিক বাস্তবায়নের উদাহরণ দেখুন
যেখানে পর্যবেক্ষণগুলি সত্যই জ্বলজ্বল করে
আসুন প্রতিটি কোডস্ট্রোক দিয়ে শেষ পয়েন্টটি হাতুড়ি না করে আমাদের কোডটি পরিবর্তন করুন তবে ব্যবহারকারী কেবল ৪০০ এমএসের জন্য টাইপ করা বন্ধ করলে কেবল একটি অনুরোধ প্রেরণ করুন
এ জাতীয় সুপার পাওয়ার উন্মোচন করতে আমাদের প্রথমে এমন একটি Observable<string>
অনুসন্ধানের শব্দটি প্রস্তুত করা উচিত যা ব্যবহারকারীর টাইপ করে formControl
। এই নির্দেশিকাটি ব্যবহার করতে, আমাদের প্রথমে ReactiveFormsModule
আমাদের অ্যাপ্লিকেশন মডিউলটিতে আমদানি করা দরকার ।
app.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { JsonpModule } from '@angular/http';
import { ReactiveFormsModule } from '@angular/forms';
@NgModule({
imports: [BrowserModule, JsonpModule, ReactiveFormsModule]
declarations: [AppComponent],
bootstrap: [AppComponent]
})
export class AppModule {}
একবার আমদানি হয়ে গেলে, আমরা আমাদের টেম্পলেট থেকে ফর্মকন্ট্রোল ব্যবহার করতে পারি এবং এটি "টার্ম" নামটিতে সেট করতে পারি।
<input type="text" [formControl]="term"/>
আমাদের উপাদান, আমরা একটি দৃষ্টান্ত তৈরি FormControl
থেকে @angular/form
এবং আমাদের উপাদান নাম মেয়াদ অধীনে একটি ক্ষেত্র যেমন এক্সপোজ।
পর্দার আড়ালে, শব্দটি স্বয়ংক্রিয়ভাবে এমন একটি Observable<string>
সম্পত্তি হিসাবে প্রকাশ করে valueChanges
যা আমরা সাবস্ক্রাইব করতে পারি। এখন যে আমাদের আছে Observable<string>
, ব্যবহারকারীর ইনপুট অতিক্রম debounceTime(400)
করা আমাদের কাছে কল করার মতোই সহজ Observable
। এটি এমন একটি নতুন ফেরত Observable<string>
দেবে যা কেবলমাত্র 400 মাইলের জন্য নতুন মান না আসায় একটি নতুন মান নির্গত হয়।
export class App {
items: Array<string>;
term = new FormControl();
constructor(private wikipediaService: WikipediaService) {
this.term.valueChanges
.debounceTime(400) // wait for 400ms pause in events
.distinctUntilChanged() // ignore if next search term is same as previous
.subscribe(term => this.wikipediaService.search(term).then(items => this.items = items));
}
}
আমাদের অ্যাপ্লিকেশন ইতিমধ্যে ফলাফলগুলি দেখায় এমন অনুসন্ধান শব্দটির জন্য অন্য একটি অনুরোধ প্রেরণ করা সম্পদের অপচয় হবে। কাঙ্ক্ষিত আচরণ অর্জনের জন্য আমাদের যা করতে হবে তা হ'ল distinctUntilChanged
আমাদের ডেকে যাওয়ার পরে অপারেটরকে কল করাdebounceTime(400)
প্লাঙ্কারে পর্যবেক্ষণযোগ্য প্রয়োগের উদাহরণ দেখুন
আউট-অফ-অর্ডার প্রতিক্রিয়া সঙ্গে তার আচরণ জন্য, পূর্ণ নিবন্ধ চেক করুন http://blog.thoughtram.io/angular/2016/01/06/taking-advantage-of-observables-in-angular2.html
অ্যাংুলারে আমি যতদূর এইচটিটিপি ব্যবহার করছি, আমি সম্মত হলাম যে সাধারণ ব্যবহারের ক্ষেত্রে ওভারসামেভার ওভার প্রতিশ্রুতি দেওয়ার সময় খুব বেশি পার্থক্য নেই। সুবিধার কোনওটিই এখানে বাস্তবে প্রাসঙ্গিক নয়। আশা করি ভবিষ্যতে কিছু উন্নত ব্যবহারের ঘটনাটি দেখতে পাবো :)
আরও জানুন
প্রতিশ্রুতি এবং পর্যবেক্ষণযোগ্য উভয়ই জাভাস্ক্রিপ্টে অ্যাসিক্রোনাস কার্যকারিতা নিয়ে কাজ করতে সহায়তা করবে । এগুলি অনেক ক্ষেত্রেই একইরকম, তবে এখনও দুজনের মধ্যে কিছু পার্থক্য রয়েছে, প্রতিশ্রুতি এমন মান যা HTTP কলগুলির asynchronous
মতো সমাধান করবে । অন্যদিকে, পর্যবেক্ষণযোগ্যরা অ্যাসিঙ্ক্রোনাস ইভেন্টগুলির ক্রম নিয়ে কাজ করে । তাদের মধ্যে প্রধান পার্থক্য নীচে তালিকাভুক্ত করা হয়েছে:
কথা দিচ্ছি:
লক্ষণীয়:
এছাড়াও, আমি পার্থক্যটি দৃশ্যমানভাবে দেখানোর জন্য নীচে আপনার জন্য গ্রাফিকাল চিত্র তৈরি করেছি:
Promise
কীভাবে প্রতিশ্রুতি দেয় তা ভেবে দেখার ভুল উপায়। Promise
এর দায়িত্ব এটা একটা ASYNC সামঞ্জস্যপূর্ণ ভাবে শুধুমাত্র হ্যান্ডেল সাফল্য বা ব্যর্থতা .. আপনি একটি HTTP অনুরোধ আপনি যদি অনুরোধটি না প্রতিশ্রুতি বাতিল, এবং হয় বাতিলের মেটান বা প্রতিশ্রুতি প্রত্যাখ্যান ফল করতে চান। jsfiddle.net/greggman/ea0yhd4p
অঙ্গীকার
Observables
এক অপারেটর পুনরায় চেষ্টা যদি আমরা কিছু অবস্থার উপর ভিত্তি করে পর্যবেক্ষণযোগ্য পুনরায় চেষ্টা করতে হবে, যখনই প্রয়োজন পুনরায় চেষ্টা করতে ব্যবহার করা যেতে পারে retryWhen ব্যবহার করা যাবে।
দ্রষ্টব্য : অপারেটরগুলির সাথে তাদের ইন্টারেক্টিভ ডায়াগ্রামগুলির একটি তালিকা এখানে RxMarbles.com এ উপলব্ধ
উত্তরগুলিতে অবজারবেবলগুলির একটি নেপথ্য অনুপস্থিত। প্রতিশ্রুতি ES7 async / অপেক্ষার ফাংশন ব্যবহার করার অনুমতি দেয়। তাদের সাথে আপনি এ্যাসক্রোনাস কোডটি লিখতে পারেন যেমন এটি একটি সিঙ্ক্রোনাস ফাংশন কল হবে, সুতরাং আপনার আর কলব্যাকের প্রয়োজন নেই। পর্যবেক্ষকরা এটি করার একমাত্র সম্ভাবনা হ'ল তাদের প্রতিশ্রুতিতে রূপান্তর করা। তবে আপনি যখন এগুলিকে প্রতিশ্রুতিতে রূপান্তর করেন, আপনার কাছে কেবলমাত্র একটি ফেরতের মান থাকতে পারে:
async function getData(){
const data = await observable.first().toPromise();
//do stuff with 'data' (no callback function needed)
}
আরও পঠন: আমি কীভাবে একটি আরএক্স পর্যবেক্ষণে অপেক্ষা করতে পারি?
প্রতিশ্রুতি এবং পর্যবেক্ষণযোগ্য উভয়ই কেবলমাত্র অ্যাসিনক্রোনাস কল পরিচালনা করে।
তাদের মধ্যে পার্থক্য এখানে:
লক্ষণীয়
প্রতিশ্রুতি
একসাথে কেবলমাত্র একক মান অনুকরণ করে
.টেন এবং। ক্যাচ ছাড়াই পরিষেবাগুলিকে কল করে
বাতিল করা যাবে না
কোনও অপারেটর সরবরাহ করে না
যদিও এই উত্তরটি দেরি হয়ে গেছে, আমি নীচের পার্থক্যগুলির সংক্ষিপ্তসার করেছি,
লক্ষণীয়:
function
যা গ্রহণ করে an observer
এবং ফেরত দেয় function Observer: an object with next, error.
subscribe/unsubscribe
তার ডেটা স্ট্রিমের অনুমতি দেয় , পর্যবেক্ষকের কাছে পরবর্তী মান নির্গমন করে, notify
পর্যবেক্ষক সম্পর্কে পর্যবেক্ষককে errors
অবহিত করে এবং অবহিত করেstream completion
function to handle next value
, ত্রুটি এবং স্ট্রিমের শেষ সরবরাহ করে (ইউআই ইভেন্টস, এইচটিপি প্রতিক্রিয়া, ওয়েব সকেটের সাথে ডেটা)।multiple values
সময়ের সাথে কাজ করেcancel-able/retry-able
এবং যেমন অপারেটরদের সমর্থন করে map,filter,reduce
etc.Observable.create()
- পর্যবেক্ষণযোগ্য যে পদ্ধতিগুলি চালনা করতে পারে - - Observer Observable.from()
একটি অ্যারে বা পুনরাবৃত্তিকে রূপান্তরিত করে - Observable Observable.fromEvent()
- কোনও ইভেন্টকে পর্যবেক্ষণযোগ্যতে Observable.fromPromise()
রূপান্তর করে - - প্রতিশ্রুতিটিকে পর্যবেক্ষণযোগ্যতে রূপান্তর করে - Observable.range()
- স্পেসিড রেঞ্জের পূর্ণসংখ্যার ক্রম ফেরত দেয়প্রতিশ্রুতি :
একটি প্রতিশ্রুতি এমন একটি কাজের প্রতিনিধিত্ব করে যা ভবিষ্যতে শেষ হবে;
প্রতিশ্রুতি হয়ে ওঠে resolved by a value
;
প্রতিশ্রুতি ব্যতিক্রম প্রত্যাখ্যান করা;
না cancellable
এবং এটি ফিরে আসেa single value
একটি প্রতিশ্রুতি একটি ফাংশন প্রকাশ করে (then)
-তখন নতুন ফিরে আসে promise
;
এর attachment
উপর ভিত্তি করে মৃত্যুদন্ড কার্যকর করা হবে
state
;
- handlers
মধ্যে guaranteed
মৃত্যুদণ্ড কার্যকর করা হয় order attached
;
আমি কেবল একটি ইস্যু মোকাবিলা করেছি যেখানে প্রতিশ্রুতিগুলি সর্বোত্তম সমাধান ছিল এবং আমি যে কেউ যদি এটি কার্যকর হয় সে ক্ষেত্রে এই প্রশ্নটি জুড়ে হোঁচট খাওয়ার জন্য এখানে এটি ভাগ করে নিচ্ছি (এটি ঠিক উত্তর ছিল যা আমি আগে খুঁজছিলাম):
একটি কৌণিক 2 প্রকল্পে আমার একটি পরিষেবা রয়েছে যা কিছু পরামিতি নেয় এবং একটি ফর্মের উপর ড্রপ ডাউন মেনুগুলি পপুলেট করার জন্য একটি মান তালিকা দেয়। যখন ফর্ম উপাদানটি আরম্ভ হয়, তখন অনেকগুলি ড্রপডাউন মেনু সংখ্যার জন্য বিভিন্ন পরামিতিগুলির সাথে একই পরিষেবাটি আমাকে একাধিকবার কল করতে হবে, তবে আমি যদি পরিষেবাটি কল করার জন্য কেবল সমস্ত ভেরিয়েবল সারি করি তবে কেবলমাত্র শেষটি সফল হয় এবং বাকী ত্রুটি হয় বাইরে। ডাটাবেস থেকে পরিষেবা আনার সময় একবারে কেবল একটি অনুরোধ পরিচালনা করতে পারে।
সমস্ত ড্রপডাউন মেনু ভেরিয়েবলগুলি সাফল্যের সাথে পপুলেশন করার একমাত্র উপায় ছিল পরিষেবাটি এমনভাবে কল করা যা শেষ অনুরোধটি শেষ না হওয়া পর্যন্ত কোনও নতুন অনুরোধটি প্রক্রিয়াজাতকরণ থেকে বাধা দেয় এবং প্রতিশ্রুতি /।
fetchValueList(listCode): Promise<any> {
return this.dataSvc.getValueList(listCode, this.stateSvc.currentContext, this.stateSvc.currentLanguageCode)
.map(response => response.json())
.toPromise();
}
initializeDropDowns() {
this.fetchValueList('First-Val-List')
.then(data => {
this.firstValList = data;
return this.fetchValueList('Second-Val-List')
}).then(data => {
this.secondValList = data;
return this.fetchValueList('Third-Val-List')
}).then(data => {
this.thirdValList = data;
}) }
আমি উপাদানটিতে ফাংশনগুলি সংজ্ঞায়িত করেছি এবং তারপরে এনজিওএনইনেটকে আর্কিটাইজড্রপডাউন () বলে।
ফেচভ্যালুলিস্ট ফাংশন একটি প্রতিশ্রুতি দেয়, সুতরাং প্রথম কলটি প্রথম তালিকা কোডটি পাস করে এবং যখন প্রতিশ্রুতিটি সমাধান হয়, তখন রিটার্নের মানটি .TL ব্লকের ডেটা ভেরিয়েবলে থাকে যেখানে আমরা এটি এই.ফার্টিভাললিস্ট ভেরিয়েবলকে নির্ধারণ করতে পারি। যেহেতু ফাংশনটি ডেটা ফিরেছে, আমরা জানি যে পরিষেবাটি শেষ হয়ে গেছে এবং দ্বিতীয় লিস্টকোড দিয়ে আবার কল করা নিরাপদ, রিটার্নের মানটি পরবর্তীটিতে ডেটা ভেরিয়েবলের মধ্যে থাকে then
সমস্ত ভেরিয়েবলগুলি পপুলেশন করার জন্য আমরা এটি যতবার প্রয়োজন শৃঙ্খল করতে পারি, এবং শেষ কোড ব্লকে আমরা কেবলমাত্র রিটার্নের স্টেটমেন্টটি বাদ দিতে পারি এবং ব্লকটি সমাপ্ত হয়।
এটি একটি খুব নির্দিষ্ট ব্যবহারের কেস যেখানে আমাদের একক পরিষেবাদি রয়েছে যা উপাদানকে আরম্ভ করার সাথে সাথে একাধিকবার কল করা প্রয়োজন এবং যেখানে পরিষেবাটি পুনরায় কল করার আগে তার ফিচারটি সম্পন্ন করতে হবে এবং কোনও মান ফিরিয়ে দিতে হবে, তবে এই ক্ষেত্রে, প্রতিশ্রুতি / .পথটি আদর্শ ছিল।
scan()
পর্যবেক্ষণযোগ্যগুলির একটি স্ট্রিম তৈরি করতে ব্যবহার করতে পারেন । যাইহোক, আপনার পদ্ধতি সম্ভবত আরও স্পষ্ট এবং বোঝা সহজ।
আমি বিশ্বাস করি অন্য সমস্ত উত্তরগুলি আপনার সন্দেহগুলি মুছে ফেলা উচিত। তবুও, আমি কেবল যুক্ত করতে চেয়েছিলাম যে পর্যবেক্ষণগুলি ফাংশনাল প্রোগ্রামিংয়ের উপর ভিত্তি করে রয়েছে এবং আমি এটির সাথে মানচিত্র, ফ্ল্যাটম্যাপ, হ্রাস, জিপ জাতীয় ফাংশনগুলি খুব দরকারী বলে মনে করি। বিশেষত যখন এটি API অনুরোধের উপর নির্ভর করে ওয়েব অবিচ্ছিন্নতা অর্জন করে তা নির্মম উন্নতি।
আমি দৃ document ়ভাবে এই ডকুমেন্টেশনটি সুপারিশ করছি , যেহেতু এটি বিক্রিয়াএক্সের অফিশিয়াল ডকুমেন্টেশন এবং আমি এটি সেখানে সবচেয়ে পরিষ্কার বলে মনে করি clear
আপনি যদি পর্যবেক্ষণে প্রবেশ করতে চান তবে আমি এই 3-অংশের পোস্টটি প্রস্তাব করব: http://blog.danlew.net/2014/09/15/grokking-rxjava-part-1/
যদিও এটি আরএক্সজাবার জন্য বোঝানো হয়েছে, ধারণাগুলি একই রকম এবং এটি সত্যই সুন্দরভাবে ব্যাখ্যা করা হয়েছে। প্রতিক্রিয়াশীল ডকুমেন্টেশনে আপনার প্রতিটি ফাংশনের সমতুল্যতা রয়েছে। আপনাকে অবশ্যই আরএক্সজেএসের সন্ধান করতে হবে।
অবিচ্ছিন্ন আচরণের জন্য আপনি সর্বদা একটি পর্যবেক্ষণযোগ্য ব্যবহার করতে পারেন যেহেতু একটি পর্যবেক্ষণযোগ্য সমস্ত কার্যকারিতা যা প্রতিশ্রুতি দেয় (+ অতিরিক্ত)। তবে, কখনও কখনও এই অতিরিক্ত কার্যকারিতা যা পর্যবেক্ষণযোগ্যরা অফার করে তা প্রয়োজন হয় না। তারপরে এটি ব্যবহার করার জন্য কোনও লাইব্রেরি আমদানি করা অতিরিক্ত ওভারহেড হবে।
আপনি যখন ফলাফলটি প্রসেস করতে চান এমন একক অ্যাসিঙ্ক অপারেশন থাকবে তখন প্রতিশ্রুতি ব্যবহার করুন । উদাহরণ স্বরূপ:
var promise = new Promise((resolve, reject) => {
// do something once, possibly async
// code inside the Promise constructor callback is getting executed synchronously
if (/* everything turned out fine */) {
resolve("Stuff worked!");
}
else {
reject(Error("It broke"));
}
});
//after the promise is resolved or rejected we can call .then or .catch method on it
promise.then((val) => console.log(val)) // logs the resolve argument
.catch((val) => console.log(val)); // logs the reject argument
সুতরাং একটি প্রতিশ্রুতি এমন কিছু কোড কার্যকর করে যেখানে এটি সমাধান করে বা প্রত্যাখ্যান করে। যদি সমাধান বা প্রত্যাখাত হয় বলা হয় প্রতিশ্রুতি মুলতুবি থাকা অবস্থায় থেকে একটি সমাধান বা প্রত্যাখ্যাত রাষ্ট্র হয় to প্রতিশ্রুতিবদ্ধ রাষ্ট্রটি সমাধান করা হলে then()
পদ্ধতিটি বলা হয়। প্রতিশ্রুতিবদ্ধ রাষ্ট্রটি প্রত্যাখাত হলে, catch()
পদ্ধতিটি বলা হয়।
সময়ের সাথে সাথে যখন কোনও স্ট্রিম (ডেটার) থাকে তখন অবজারভেবলগুলি ব্যবহার করুন । একটি স্ট্রিম ডেটা উপাদানগুলির একটি ক্রম যা সময়ের সাথে সাথে উপলব্ধ করা হচ্ছে । স্ট্রিমগুলির উদাহরণ হ'ল:
পরের ইভেন্টটি কখন ঘটেছিল, কখন ত্রুটি ঘটেছিল বা পর্যবেক্ষণযোগ্য সম্পন্ন হয় তা পর্যবেক্ষণে নিজেই নির্দিষ্ট করা হয় । তারপরে আমরা এই পর্যবেক্ষণযোগ্যতে সাবস্ক্রাইব করতে পারি, যা এটি সক্রিয় করে এবং এই সাবস্ক্রিপশনে, আমরা 3 কলব্যাকগুলিতে পাস করতে পারি (সবসময় সব কিছুতেই পাস করতে হবে না)। সাফল্যের জন্য কার্যকর করা একটি কলব্যাক, ত্রুটির জন্য একটি কলব্যাক এবং সমাপ্তির জন্য একটি কলব্যাক। উদাহরণ স্বরূপ:
const observable = Rx.Observable.create(observer => {
// create a single value and complete
observer.onNext(1);
observer.onCompleted();
});
source.subscribe(
x => console.log('onNext: %s', x), // success callback
e => console.log('onError: %s', e), // error callback
() => console.log('onCompleted') // completion callback
);
// first we log: onNext: 1
// then we log: onCompleted
একটি পর্যবেক্ষণযোগ্য তৈরি করার সময় এটিতে একটি কলব্যাক ফাংশন প্রয়োজন যা একটি পর্যবেক্ষককে যুক্তি হিসাবে সরবরাহ করে। এই পর্যবেক্ষক, আপনি তারপর কল করতে পারেন onNext
, onCompleted
, onError
। তারপরে যখন পর্যবেক্ষণযোগ্য এটিতে সাবস্ক্রাইব হবে তখন সাবস্ক্রিপশনে পাস হওয়া সংশ্লিষ্ট কলব্যাকগুলি কল করবে।
প্রতিশ্রুতি - একক ভবিষ্যতের মান প্রদান করুন। অলস না . বাতিল-সক্ষম নয়। এটি হয় প্রত্যাখ্যান বা সমাধান করবে।
পর্যবেক্ষণযোগ্য - একাধিক ভবিষ্যতের মান সরবরাহ করুন। অলস বাতিল-সক্ষম এটি অন্যান্য পদ্ধতি লাইভ ম্যাপ, ফিল্টার, হ্রাস প্রদান করে।
const promise = new Promise(resolve => {
setTimeout(() => {
resolve("Hello from a Promise!");
}, 2000);
});
promise.then(value => console.log(value));
এখন পর্যবেক্ষণযোগ্য উদাহরণ। এখানেও আমরা একটি ফাংশন পর্যবেক্ষণযোগ্য, অ্যাসিঙ্ক টাস্কটি পরিচালনা করার জন্য একটি পর্যবেক্ষককে পাস করি। প্রতিশ্রুতিতে সমাধানের বিপরীতে এর নিম্নলিখিত পদ্ধতি রয়েছে এবং তার পরিবর্তে সাবস্ক্রাইব করে।
সুতরাং উভয়ই অ্যাসিঙ্ক কার্য পরিচালনা করে। এবার আসুন পার্থক্যটি দেখুন।
const observable = new Observable(observer => {
setTimeout(() => {
observer.next('Hello from a Observable!');
}, 2000);
});
observable.subscribe(value => console.log(value));
প্রতিশ্রুতি
লক্ষণীয়
প্রতিশ্রুতি এবং পর্যবেক্ষণযোগ্য উভয়ই অ্যাসিক্রোনাস অপারেশনগুলির মোকাবেলায় সহায়তা করে। এই অ্যাসিক্রোনাস অপারেশনগুলি করা হয়ে গেলে তারা নির্দিষ্ট কলব্যাকগুলি কল করতে পারে।
কৌণিকটি পর্যবেক্ষণগুলি ব্যবহার করে যা এইচটিটিপি নিয়ে কাজ করার প্রতিশ্রুতির পরিবর্তে আরএক্সজেএস থেকে আসে
Below are some important differences in promises & Observables.
যখন একটি অ্যাসিঙ্ক ক্রিয়াকলাপ শেষ হয়ে যায় বা ব্যর্থ হয় তখন কোনও প্রতিশ্রুতি একটি একক ইভেন্টের প্রকাশ করে।
একটি পর্যবেক্ষণযোগ্য একটি স্ট্রিমের মতো (অনেক ভাষায়) এবং কমপক্ষে শূন্য বা আরও বেশি ইভেন্টগুলিতে পাস করার অনুমতি দেয় যেখানে প্রতিটি ইভেন্টের জন্য কলব্যাকের প্রয়োজন হয়।
এটি প্রতিশ্রুতির হাইলাইটগুলি এবং আরও অনেক কিছু দেয় বলে প্রায়শই পর্যবেক্ষণযোগ্য প্রতিশ্রুতির চেয়ে বেশি পছন্দ হয়। পর্যবেক্ষণযোগ্য দ্বারা আপনার 0, 1, বা বিভিন্ন ইভেন্ট হ্যান্ডেল করা দরকার কিনা তা বিবেচনা করে না। আপনি প্রতিটি মামলার জন্য অনুরূপ এপিআই ব্যবহার করতে পারেন।
প্রতিশ্রুতি: প্রতিশ্রুতি একক মান প্রকাশ করে
উদাহরণ স্বরূপ:
const numberPromise = new Promise((resolve) => {
resolve(5);
resolve(10);
});
numberPromise.then(value => console.log(value));
// still prints only 5
পর্যবেক্ষণযোগ্য: একটি সময়কালে একাধিক মান নির্ধারণ করে
উদাহরণ স্বরূপ:
const numberObservable = new Observable((observer) => {
observer.next(5);
observer.next(10);
});
numberObservable.subscribe(value => console.log(value));
// prints 5 and 10
আমরা এমন একটি স্ট্রিমের মতো পর্যবেক্ষনের কথা ভাবতে পারি যা সময়ের সাথে সাথে একাধিক মান নির্গত হয় এবং নির্গত প্রতিটি আইটেমের জন্য একই কলব্যাক ফাংশনটি আহ্বান করা হয় যাতে আমরা পর্যবেক্ষণযোগ্য এর সাহায্যে একই এপিআই ব্যবহার করতে পারি অ্যাসিঙ্ক্রোনাস ডেটা পরিচালনা করতে। সেই ডেটা কোনও একক মান বা একাধিক মান হিসাবে কিছু সময়ের জন্য প্রেরণ করা হয়।
প্রতিশ্রুতি:
লক্ষণীয়:
প্রতিশ্রুতিশীল একাধিক মান নির্গত করে যখন প্রতিশ্রুতি একক মান নির্ধারণ করে। সুতরাং, এইচটিটিপি অনুরোধ পরিচালনা করার সময়, প্রতিশ্রুতি একই অনুরোধের জন্য একটি একক প্রতিক্রিয়া পরিচালনা করতে পারে, তবে একই অনুরোধে যদি একাধিক প্রতিক্রিয়া থাকে তবে আমাদের অবজার্ভেবল ব্যবহার করতে হবে। হ্যাঁ, পর্যবেক্ষণযোগ্য একই অনুরোধের জন্য একাধিক প্রতিক্রিয়া পরিচালনা করতে পারে।
প্রতিশ্রুতি
const promise = new Promise((data) =>
{ data(1);
data(2);
data(3); })
.then(element => console.log(‘Promise ‘ + element));
আউটপুট
Promise 1
লক্ষণীয়
const observable = new Observable((data) => {
data.next(1);
data.next(2);
data.next(3);
}).subscribe(element => console.log('Observable ' + element));
আউটপুট
Observable 1
Observable 2
Observable 3
নীচে প্রতিশ্রুতি ও পর্যবেক্ষণে কিছু গুরুত্বপূর্ণ পার্থক্য রয়েছে।
প্রতিশ্রুতি
লক্ষণীয়
আরও ভাল বোঝার জন্য https://stackblitz.com/edit/observable-vs-promises দেখুন
আমি প্রচুর লোককে তর্কটি ব্যবহার করে দেখতে পাচ্ছি যে পর্যবেক্ষণযোগ্য "বাতিলযোগ্য" তবে এটি প্রতিশ্রুতি "বাতিল" হিসাবে তৈরি করা বরং তুচ্ছ
function cancellablePromise(body) {
let resolve, reject;
const promise = new Promise((res, rej) => {
resolve = res; reject = rej;
body(resolve, reject)
})
promise.resolve = resolve;
promise.reject = reject;
return promise
}
// Example 1: Reject a promise prematurely
const p1 = cancellablePromise((resolve, reject) => {
setTimeout(() => resolve('10', 100))
})
p1.then(value => alert(value)).catch(err => console.error(err))
p1.reject(new Error('denied')) // expect an error in the console
// Example: Resolve a promise prematurely
const p2 = cancellablePromise((resolve, reject) => {
setTimeout(() => resolve('blop'), 100)
})
p2.then(value => alert(value)).catch(err => console.error(err))
p2.resolve(200) // expect an alert with 200
সংক্ষিপ্ত উত্তর :
লক্ষণীয় হয় ভাল , এটি সব আছে অঙ্গীকার বৈশিষ্ট্য প্লাস অতিরিক্ত বৈশিষ্ট্য।
দীর্ঘ উত্তর:
প্রতিজ্ঞা করেন:
লক্ষণীয়:
যদিও স্বীকৃত উত্তরটি সাধারণভাবে ভাল তবে আমি মনে করি না যে এটি জোর দেয় যে কৌণিক উপাদানগুলির সাথে কাজ করার সময় আপনি প্রায় সর্বদা একটি পর্যবেক্ষণযোগ্য ব্যবহার করতে চান কারণ এটি বাতিলকরণকে সমর্থন করে। প্রতিশ্রুতি বাতিল হতে পারে না এবং আপনার উপাদানটি ধ্বংস হয়ে গেলেও সমাধান করবে। কৌণিক এটি না হওয়া পর্যন্ত ক্ষমা করে থাকে।
উদাহরণস্বরূপ, কোনও ধ্বংস হওয়া উপাদানটিতে কোনও ম্যানুয়াল পরিবর্তন সনাক্তকরণ ব্যতিক্রম ঘটায়:
ngOnInit() {
// promise api
this.service.getData().then(d => {
this.data = d;
this.changeDetectorRef.detectChanges();
});
// observable api
this.service.getData().pipe(takeUntil(this.unsubscribe)).subscribe((d) => {
this.data = d;
this.changeDetectorRef.detectChanges();
});
}
প্রতিশ্রুতি সমাধানের আগে যদি আপনার উপাদানটি বিনষ্ট হয় তবে প্রতিশ্রুতিটি সমাধান হওয়ার পরে আপনি একটি attempt to use destroyed view
ত্রুটি পাবেন ।
বিকল্পভাবে, আপনি যদি অবলম্বনগুলি টেকউইনটিল প্যাটার্নের সাথে ব্যবহার করেন তবে আপনার উপাদানটি ধ্বংস হওয়ার সাথে সাথেই সাবস্ক্রিপশন বাতিল হয়ে যাবে।
এটি সামান্য একটি উদাহরণযুক্ত উদাহরণস্বরূপ তবে ধ্বংস হওয়া কোন উপাদানটির কোড কার্যকর করা সম্ভবত বাগগুলি নিয়ে যেতে চলেছে। যদি না আপনি আসলে কোনও কারণে এটি করতে চান: পি
টিউটোরিয়াল এবং ডক্সের প্রথম পড়া থেকে আমি এর মধ্যে যা ছড়িয়েছি তা স্পষ্ট ছিল না মাল্টিকাস্টিংয়ের ধারণা।
নিশ্চিত হয়ে নিন যে আপনি ডিফল্টরূপে, একাধিক সাবস্ক্রিপশন পর্যবেক্ষণে একাধিক ফাঁসি কার্যকর করতে পারে trigger একক HTTP কল পর্যবেক্ষণযোগ্য একাধিক সাবস্ক্রিপশন আপনি .share()
(মাল্টিকাস্টিং সক্ষম না করা ) একাধিক অভিন্ন HTTP কলগুলি ট্রিগার করবে ।
একটি প্রতিশ্রুতি আপনাকে একবারে একটি জিনিস মোকাবেলা করতে বাধ্য করে, এর ডেটা আনপ্রেট করে, ব্যতিক্রমগুলি পরিচালনা করে, অ্যাসিঙ্ক / প্রতীক্ষার মতো শীতল জিনিসের জন্য ভাষা সমর্থন দেয় এবং অন্যথায় এটি বেশ নগ্ন হয়।
একটি পর্যবেক্ষণযোগ্যটিতে প্রচুর ঘণ্টা এবং হুইসেল থাকে তবে আপনার যে শক্তি নিয়ে কাজ করছেন তা বোঝার প্রয়োজন বা এটির অপব্যবহার করা যেতে পারে।
প্রতিশ্রুতি:
একটি অ্যাসিঙ্ক ইভেন্ট হ্যান্ডলার - প্রতিশ্রুতি বস্তু একটি অ্যাসিঙ্ক্রোনাস অপারেশনের শেষ সমাপ্তি (বা ব্যর্থতা) এবং এর ফলাফলের মান উপস্থাপন করে।
সিনট্যাক্স: নতুন প্রতিশ্রুতি (নির্বাহক);
উদাহরণ:
var promise_eg = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve('foo');
}, 300);
});
promise_eg.then(function(value) {
console.log(value);
// expected output: "foo"
});
console.log(promise_eg);
প্রতিশ্রুতি সম্পর্কে: এটিতে একটি পাইপলাইন রয়েছে তাই এটি ডাকা হলে কেবল এটির মান ফিরে আসবে। এটির ওয়ান ওয়ে হ্যান্ডলারটি একবার কল করলে আপনি বাতিল করতে পারবেন না। আপনি চারপাশে, কখন () এবং তারপরে () খেলতে পারবেন দরকারী সিনট্যাক্স
Observables:
পর্যবেক্ষণযোগ্য হ'ল সময়ের সাথে সাথে একাধিক মানের অলস সংগ্রহ। এটি আসিঙ্ক অপারেশনের জন্য সত্যই দুর্দান্ত পন্থা। এটি আরএক্সজেএস দিয়ে করা যেতে পারে যার ক্রস প্ল্যাটফর্ম সমর্থনটি কৌনিক / প্রতিক্রিয়া ইত্যাদির সাহায্যে ব্যবহার করতে পারে has
এটি স্ট্রিম লাইনারের মতো কাজ করে। মাল্টি পাইপলাইন হতে পারে। একবারে সংজ্ঞায়িত হয়ে গেলে আপনি অনেক জায়গায় রিটার্নের ফলাফল পেতে সাবস্ক্রাইব করতে পারেন।
সিনট্যাক্স: import * as Rx from "@reactivex/rxjs";
টু ডিআইডি:
Rx.Observable.fromEvent(button, "click"),
Rx.Subject()
ইত্যাদি
সাবস্ক্রাইব করতে: RxLogger.getInstance();
উদাহরণ:
import { range } from 'rxjs';
import { map, filter } from 'rxjs/operators';
range(1, 200).pipe(
filter(x => x % 2 === 1),
map(x => x + x)
).subscribe(x => console.log(x));
যেহেতু এটি মাল্টি পাইপলাইন সমর্থন করে আপনি বিভিন্ন স্থানে ফলাফল সাবস্ক্রাইব করতে পারেন, এটির প্রতিশ্রুতির চেয়ে অনেক বেশি সম্ভাবনা রয়েছে।
ব্যবহার: এর
মতো আরও সম্ভাবনা রয়েছেmap, filter, pipe, map, concatMap etc
পর্যবেক্ষণগুলি প্রায়শই প্রতিশ্রুতির সাথে তুলনা করা হয়। এখানে কিছু মূল পার্থক্য রয়েছে:
পর্যবেক্ষণযোগ্য ঘোষিত হয়; সাবস্ক্রিপশন না হওয়া পর্যন্ত গণনা শুরু হয় না। প্রতিশ্রুতি তৈরি করার সাথে সাথেই কার্যকর করা হবে। এটি রেসিপিগুলি সংজ্ঞায়িত করার জন্য পর্যবেক্ষণযোগ্যকে দরকারী করে তোলে যা যখনই আপনার ফলাফলের প্রয়োজন হয় তখন চালানো যেতে পারে।
পর্যবেক্ষণযোগ্যরা অনেক মান সরবরাহ করে। প্রতিশ্রুতি এক প্রদান। এটি সময়ের সাথে একাধিক মান পাওয়ার জন্য পর্যবেক্ষণযোগ্যকে দরকারী করে তোলে।
চেইঞ্জিং এবং সাবস্ক্রিপশনের মধ্যে পর্যবেক্ষণযোগ্যরা পার্থক্য করতে পারে ate প্রতিশ্রুতিগুলিতে কেবল। কাজটি সম্পাদন না করেই সিস্টেমের অন্যান্য অংশগুলি ব্যবহার করতে জটিল রূপান্তর রেসিপি তৈরির জন্য পর্যবেক্ষণযোগ্যকে দরকারী করে তোলে।
পর্যবেক্ষণযোগ্য সাবস্ক্রাইব () ত্রুটিগুলি পরিচালনা করার জন্য দায়ী। সন্তানের প্রতিশ্রুতিগুলিতে চাপের ত্রুটিগুলি প্রতিশ্রুতি দেয়। এটি কেন্দ্রিয়ায়িত এবং প্রত্যাশাযোগ্য ত্রুটি পরিচালনার জন্য পর্যবেক্ষণযোগ্যকে দরকারী করে তোলে।
এটি সবচেয়ে সহজ পার্থক্য যা আপনি অ্যানগুলার.আইও ডক্সে খুঁজে পেতে পারেন। বাকী উত্তর বেশিরভাগ দ্বারা দেওয়া হয় তার নিজের জায়গায় সঠিক
প্রতিশ্রুতি শুধুমাত্র একক মান বা সমাধানের জন্য ফোকাস করা হয়, পর্যবেক্ষণযোগ্য ডেটা স্ট্রিম।
পর্যবেক্ষকগুলি বাতিল হতে পারে তবে প্রতিশ্রুতি বাতিল হতে পারে না।
সবচেয়ে কম পরিচিত একজন, আমার কাছে কমপক্ষে
পর্যবেক্ষণযোগ্য ও প্রতিশ্রুতিগুলি জাভাস্ক্রিপ্ট / টাইপ স্ক্রিপ্টে অ্যাসিক্রোনাস কার্যকারিতা নিয়ে কাজ করতে আমাদের সহায়তা করছে are এগুলি অনেক ক্ষেত্রে খুব একই রকম, তবে তাদের মধ্যে এখনও কিছু পার্থক্য রয়েছে।
ইতিমধ্যে এই বিষয়টিতে প্রচুর উত্তর রয়েছে তাই আমি কোনও অতিরিক্ত বাছাই করা যুক্ত করব না।
তবে যে কেউ কেবলমাত্র পর্যবেক্ষণযোগ্য / কৌণিক শিখতে শুরু করেছেন এবং কোনটি প্রতিশ্রুতির সাথে তুলনা করবেন তা অবাক করে দেওয়ার জন্য , আমি আপনাকে সুপারিশ করব যে আপনি সবকিছু পর্যবেক্ষণযোগ্য রাখুন এবং আপনার প্রকল্পের বিদ্যমান প্রতিশ্রুতিগুলি পর্যবেক্ষণযোগ্যতে রূপান্তর করুন।
কেবল কৌণিক কাঠামো নিজেই এবং এর সম্প্রদায়গুলি সমস্ত পর্যবেক্ষণযোগ্য ব্যবহার করছে। সুতরাং যখন আপনি কাঠামো পরিষেবাগুলি বা তৃতীয় পক্ষের মডিউলগুলি একীভূত করবেন এবং সমস্ত কিছু একসাথে শৃঙ্খলিত করবেন তখন এটি উপকারী হবে।
যদিও আমি সমস্ত নিম্নবিত্তদের প্রশংসা করি তবে আমি এখনও উপরে আমার মতামতটি জোর দিয়ে বলি যদি না কেউ কেউ কয়েকটি দৃশ্যের তালিকা তৈরির জন্য যথাযথ মন্তব্য না করে যা আপনার পর্যবেক্ষণের উপরে প্রতিশ্রুতিগুলি ব্যবহার করতে আপনার কৌণিক প্রকল্পে এখনও কার্যকর হতে পারে।
অবশ্যই, কোনও মতামত সব ক্ষেত্রেই 100% সঠিক নয় তবে কমপক্ষে আমি মনে করি যে কৌণিক কাঠামোয় প্রয়োগ করা নিয়মিত বাণিজ্যিক প্রকল্পগুলির জন্য 98% সময়, পর্যবেক্ষণযোগ্য হ'ল সঠিক উপায়।
আপনার সাধারণ শখের প্রকল্পের শুরুতে আপনি এটি পছন্দ না করলেও, আপনি শীঘ্রই কৌণিক ব্যবস্থায় প্রায়শই সমস্ত উপাদান অনুধাবন করতে পারবেন এবং কৌণিক বন্ধুত্বপূর্ণ তৃতীয় পক্ষের কাঠামোর বেশিরভাগই পর্যবেক্ষণগুলি ব্যবহার করছেন এবং তারপরে আপনি আপনার প্রতিশ্রুতি নিয়মিত পর্যবেক্ষণযোগ্য হিসাবে রূপান্তর করে তাদের সাথে যোগাযোগ করার জন্য।
এই উপাদানগুলির মধ্যে অন্তর্ভুক্ত রয়েছে তবে সীমাবদ্ধ নয়: এইচটিপিপি্লিয়েন্ট, ফর্ম নির্মাতা, কৌণিক উপাদান মডিউল / সংলাপ, এনজিআরএক্স স্টোর / এফেক্টস এবং এনজিএক্স-বুটস্ট্র্যাপ।
প্রকৃতপক্ষে, গত 2 বছরে আমি যে অ্যাংুলার ইকো-সিস্টেমটি মোকাবিলা করেছি তার একমাত্র প্রতিশ্রুতি APP_INITIALIZER
।