डेफर से मिलते हैं

पिछले लेख में, हमने देखा कि कैसे अपने खुद के आरएक्सजेएस स्टेटमेंट बनाए जाएं। अब मैं एक छोटे से ज्ञात रचना ऑपरेटर के बारे में बात करना चाहता हूं - 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);

// The same concept as using a function
const randNum = () => of(Math.random());
randNum2().subscribe(console.log);
randNum2().subscribe(console.log);

एक और उदाहरण है जब आपको किसी वादे के निष्पादन में देरी करने की आवश्यकता होती है।


// This already executing regardless the numbers of handlers
const promise = new Promise(resolve => {
  resolve();
});

// Deferring the creation of the promise until someone subscribes
const promiseDefered = defer(() => {
  return new Promise(resolve => {
    resolve();
  });
});

promiseDefered.subscribe(console.log);

श्रोताओं की संख्या की परवाह किए बिना वादों को तुरंत निष्पादित किया जाता है। आप एक स्ट्रीम (जैसे आलसी) का उपयोग करके एक वादा देखो कर सकते हैं defer


All Articles