पिछले लेख में, हमने देखा कि कैसे अपने खुद के आरएक्सजेएस स्टेटमेंट बनाए जाएं। अब मैं एक छोटे से ज्ञात रचना ऑपरेटर के बारे में बात करना चाहता हूं - defer
- और समझाता हूं कि आप इसे कुछ स्थितियों के लिए कैसे उपयोग कर सकते हैं
मान लें कि आपको एक ऑपरेटर बनाने की ज़रूरत है जो एक फ़ंक्शन लेता है और इसे केवल एक बार निष्पादित करता है, पहली बार यह एक मूल्य प्राप्त करता है। हम इसे टैपऑन नाम के तहत लागू करते हैं
function tapOnce<T>(fn: Function): OperatorFunction<T, T> {
return function(source: Observable<any>) {
let run = false;
return source.pipe(
tap(() => {
if (!run) {
fn();
run = true;
}
})
);
};
}
कोड स्पष्ट है - यह tap
फ़ंक्शन को चलाने के लिए उपयोग किया जाता है, ध्वज को run
केवल एक बार ऐसा करने के लिए आवश्यक है। अब हम ऑपरेटर का उपयोग करते हैं।
const source = interval(5000).pipe(
tapOnce(() => console.log('+')
));
source.subscribe(console.log);
सब कुछ काम करता है, प्लस चिह्न केवल पहली बार में कंसोल में प्रदर्शित होता है। अब सब्सक्राइबर को जोड़ें।
const source = interval(5000).pipe(
tapOnce(() => console.log('+')
));
source.subscribe(console.log);
source.subscribe(console.log);
यदि आप कंसोल को देखते हैं - केवल एक प्लस है। समस्या यह है कि दोनों ग्राहक एक ही शाब्दिक वातावरण का उपयोग करते हैं और एक ही चर का संदर्भ देते हैं run
। हमें किसी सूत्र की रचना को स्थगित करने का एक तरीका चाहिए जब तक कि कोई सदस्यता न ले।
मदद करेगा defer
import { defer } from 'rxjs';
function tapOnce<T>(fn: Function): OperatorFunction<T, T> {
return function(source: Observable<any>) {
return defer(() => {
let run = false;
return source.pipe(
tap(() => {
if (!run) {
fn();
run = true;
}
})
);
});
};
}
ऑपरेटर defer
एक फ़ंक्शन को स्वीकार करता है जिसे वापस लौटना चाहिए ObservableInput
। अंदर कोड defer
केवल सदस्यता पर निष्पादित किया जाएगा, और निर्माण के दौरान नहीं। इस दृष्टिकोण और जेएस क्लोजर के लिए धन्यवाद का उपयोग करते हुए, प्रत्येक ग्राहक अपने स्वयं के शाब्दिक वातावरण का उपयोग करता है।
आइए defer
एक बेहतर समझ के लिए हमारा सरल कार्यान्वयन बनाएं ।
function defer(observableFactory: () => ObservableInput<any>) {
return new Observable(subscriber => {
const source = observableFactory();
return source.subscribe(subscriber);
});
}
defer
एक नया स्ट्रीम लौटाता है, जो फ़ैक्टरी फ़ंक्शन द्वारा सदस्यता के क्षण में बनाया जाता है, और एक स्रोत के रूप में उपयोग किया जाएगा।
यहां और अधिक उदाहरण हैं जहां यह उपयोगी होगा defer
। कहें कि हमारे पास एक अभिव्यक्ति है जिसे किसी को साइन अप करने पर गिनने की आवश्यकता है। उदाहरण के लिए
const randNum = of(Math.random());
randNum.subscribe(console.log);
randNum.subscribe(console.log);
इस उदाहरण में, प्रत्येक ग्राहक को समान यादृच्छिक मूल्य प्राप्त होगा। आप इसे सही कर सकते हैं ताकि सदस्यता लेते समय अभिव्यक्ति को गिना जाए, घोषणा करते समय नहीं।
const randNum = defer(() => of(Math.random()));
randNum2.subscribe(console.log);
randNum2.subscribe(console.log);
const randNum = () => of(Math.random());
randNum2().subscribe(console.log);
randNum2().subscribe(console.log);
एक और उदाहरण है जब आपको किसी वादे के निष्पादन में देरी करने की आवश्यकता होती है।
const promise = new Promise(resolve => {
resolve();
});
const promiseDefered = defer(() => {
return new Promise(resolve => {
resolve();
});
});
promiseDefered.subscribe(console.log);
श्रोताओं की संख्या की परवाह किए बिना वादों को तुरंत निष्पादित किया जाता है। आप एक स्ट्रीम (जैसे आलसी) का उपयोग करके एक वादा देखो कर सकते हैं defer
।