angular वादा बनाम अवलोकन योग्य




promise rxjs (12)

पक्का वादा:

  • एक भविष्य का मूल्य प्रदान करें;
  • आलसी नहीं;
  • रद्द करने योग्य नहीं;

नमूदार:

  • समय के साथ कई मूल्यों को उत्सर्जित करता है;
  • आलसी;
  • रद्द करने योग्य;
  • मानचित्र, फ़िल्टर, कम करने और समान ऑपरेटर का समर्थन करता है

यदि आप चाहें तो कोणीय में HTTP को कॉल करते समय आप अवलोकन के बजाय वादे का उपयोग कर सकते हैं।

क्या कोई व्यक्ति कोणीय में Promise और Observable बीच अंतर को समझा सकता है?

प्रत्येक मामले पर एक उदाहरण दोनों मामलों को समझने में सहायक होगा। हम किस मामले में प्रत्येक मामले का उपयोग कर सकते हैं?


Promises और Observables दोनों हमें अमूर्तताओं के साथ प्रदान करते हैं जो हमें हमारे अनुप्रयोगों की असीमित प्रकृति से निपटने में मदद करते हैं। उनके बीच का अंतर स्पष्ट रूप से @ गुंटर और @ रेल्लू द्वारा इंगित किया गया था।

चूंकि एक कोड स्निपेट हजारों शब्दों के लायक है, इसलिए उन्हें समझने के लिए नीचे दिए गए उदाहरण को छोड़ दें।

भयानक article लिए धन्यवाद @ क्रिस्टोफ Burgdorf

कोणीय HTTP से निपटने के वादे के बजाय Rx.js Observables का उपयोग करता है।

मान लीजिए कि आप एक खोज फ़ंक्शन बना रहे हैं जो आपको टाइप करते समय तत्काल परिणाम दिखाए। परिचित ध्वनि लेकिन उस कार्य के साथ आने वाली कई चुनौतियां हैं।

  • जब भी उपयोगकर्ता कुंजी दबाता है, हम सर्वर एंडपॉइंट को हिट नहीं करना चाहते हैं, तो उन्हें HTTP अनुरोधों के तूफान के साथ बाढ़ करना चाहिए। असल में, जब हम उपयोगकर्ता ने प्रत्येक कीस्ट्रोक के बजाय टाइपिंग बंद कर दी है तो हम केवल इसे हिट करना चाहते हैं।
  • बाद के अनुरोधों के लिए एक ही क्वेरी पैरा के साथ खोज एंडपॉइंट को मत मारो।
  • आउट ऑफ़ ऑर्डर प्रतिक्रियाओं के साथ सौदा करें। जब हमारे पास एक ही समय में उड़ान भरने के लिए कई अनुरोध होते हैं तो हमें उन मामलों के लिए जिम्मेदार होना चाहिए जहां वे अप्रत्याशित क्रम में वापस आते हैं। कल्पना कीजिए कि हम पहले कंप्यूटर टाइप करते हैं , रुकते हैं, एक अनुरोध निकलता है, हम कार टाइप करते हैं, रुकते हैं, एक अनुरोध बाहर निकलता है। अब हमारे पास उड़ान में दो अनुरोध हैं। दुर्भाग्यवश, अनुरोध जो कंप्यूटर के लिए परिणाम लेता है अनुरोध के बाद वापस आता है जो कार के परिणाम लेता है।

डेमो में केवल दो फाइलें app.ts : app.ts और wikipedia-service.ts app.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]);
  }
}

हम किसी दिए गए खोज शब्द के साथ विकिपीडिया एपीआई के खिलाफ GET अनुरोध करने के लिए Jsonp सेवा इंजेक्शन दे रहे हैं। ध्यान दें कि हम एक toPromise Observable<Response> एक Promise<Response> से प्राप्त करने के लिए toPromise कॉल toPromise । आखिरकार एक 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 लूप प्राप्त कर सकें और हमारे लिए एक सूची तैयार कर सकें।

Plunker पर वादा-आधारित कार्यान्वयन का उदाहरण देखें

जहां वेधशाला वास्तव में चमकता है

चलिए अपने कोड को प्रत्येक कीस्ट्रोक के साथ एंडपॉइंट को हथियाने के लिए नहीं बदलते हैं, बल्कि इसके बजाय केवल एक अनुरोध भेजें जब उपयोगकर्ता 400 एमएस के लिए टाइप करना बंद कर देता है

ऐसी सुपर शक्तियों का अनावरण करने के लिए हमें सबसे पहले एक 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 {}

आयात करने के बाद, हम अपने टेम्पलेट के भीतर से formControl का उपयोग कर सकते हैं और इसे "टर्म" नाम पर सेट कर सकते हैं।

<input type="text" [formControl]="term"/>

हमारे घटक में, हम @angular/form से FormControl का एक उदाहरण @angular/form और इसे हमारे घटक पर नाम अवधि के तहत एक क्षेत्र के रूप में बेनकाब करते हैं।

दृश्यों के पीछे, शब्द स्वचालित रूप से एक Observable<string> संपत्ति valueChanges रूप में valueChanges जिसे हम सब्सक्राइब कर सकते हैं। अब हमारे पास एक Observable<string> , उपयोगकर्ता इनपुट पर काबू पाने के लिए हमारे Observable पर debounceTime(400) को कॉल करना उतना ही आसान है। यह एक नया Observable<string> वापस करेगा जो 400ms के लिए नए मान नहीं आ रहा है जब केवल एक नया मूल्य उत्सर्जित करेगा।

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));
  }
}

यह खोज शब्द के लिए एक और अनुरोध भेजने के लिए संसाधनों का अपशिष्ट होगा कि हमारा ऐप पहले ही परिणाम दिखाता है। वांछित व्यवहार को प्राप्त करने के लिए हमें बस इतना करना है कि हम debounceTime(400) नामक के बाद distinctUntilChanged debounceTime(400) ऑपरेटर को कॉल करना है

Plunker पर Plunker योग्य कार्यान्वयन का उदाहरण देखें

आउट ऑफ़ ऑर्डर प्रतिक्रियाओं से निपटने के लिए, कृपया पूरा लेख देखें article

जहां तक ​​मैं कोणीय में एचटीपी का उपयोग कर रहा हूं, मैं मानता हूं कि सामान्य उपयोग के मामलों में वादे पर पर्यवेक्षण का उपयोग करते समय बहुत अंतर नहीं होता है। अभ्यास में कोई भी लाभ वास्तव में प्रासंगिक नहीं है। उम्मीद है कि मैं भविष्य में कुछ उन्नत उपयोग केस देख सकता हूं :)

और अधिक जानें


वादा - एक भविष्य का मूल्य प्रदान करें। आलसी नहीं । रद्द करने योग्य नहीं है। यह या तो अस्वीकार या हल करेगा।

अवलोकन - एकाधिक भविष्य मूल्य प्रदान करें। आलसी । रद्द करें सक्षम यह अन्य तरीकों को लाइव मानचित्र, फ़िल्टर, कम प्रदान करता है।


वादे और पर्यवेक्षण दोनों केवल एसिंक्रोनस कॉल को संभालने वाले हैं। मुख्य अंतर के लिए उपरोक्त छवि को खोजें।


वादे

  1. परिभाषा: आपको असीमित रूप से कार्यों को चलाने में मदद करता है, और उनके वापसी मान (या अपवाद) का उपयोग करता है लेकिन निष्पादित होने पर केवल एक बार
  2. आलसी नहीं
  3. रद्द करने योग्य नहीं है। दो संभावित निर्णय हैं
    • अस्वीकार
    • संकल्प
  4. पुन: प्रयास नहीं किया जा सकता है (वादे को उस मूल कार्य तक पहुंच प्राप्त होनी चाहिए जिसने एक पुनः प्रयास करने के लिए वादा वापस कर दिया है, जो एक बुरा अभ्यास है)

observables

  1. परिभाषा: कार्य को असीमित रूप से चलाने में आपकी सहायता करता है, और निष्पादित होने पर निरंतर अनुक्रम ( एकाधिक बार ) में उनके वापसी मानों का उपयोग करता है।
  2. डिफ़ॉल्ट रूप से, यह आलसी है क्योंकि समय बढ़ने पर मूल्यों को उत्सर्जित करता है।
  3. बहुत सारे ऑपरेटर हैं जो कोडिंग प्रयास को सरल बनाते हैं।
  4. एक ऑपरेटर रीट्री का उपयोग कभी भी आवश्यक होने पर पुनः प्रयास करने के लिए किया जा सकता है, भले ही हमें कुछ स्थितियों के आधार पर अवलोकन करने की आवश्यकता हो, फिर भी इसका उपयोग किया जा सकता है।

    नोट : ऑपरेटरों की एक सूची उनके इंटरैक्टिव आरेखों के साथ यहां RxMarbles.com पर उपलब्ध है


पर्यवेक्षी बनाम वादे

वादे और पर्यवेक्षण , दोनों ही हमें एक आसान तरीका प्रदान करते हैं जो हमारे अनुप्रयोगों की असीमित प्रकृति की कोशिश करने में हमारी सहायता करते हैं। हालांकि, दोनों के बीच महत्वपूर्ण अंतर हैं:

  • अवलोकन अतुल्यकालिक व्यवहार के सेटअप और टियरडाउन पहलुओं को परिभाषित कर सकते हैं।
  • पर्यवेक्षक रद्द करने योग्य हैं।
  • इसके अलावा, पर्यवेक्षकों को एपीआई द्वारा प्रदान किए गए एक पुनः प्रयास ऑपरेटर का उपयोग करके पुनः प्रयास किया जा सकता है, जैसे कि पुनः प्रयास करें और पुनः प्रयास करें। दूसरी तरफ, वादे के लिए कॉलर को उस मूल कार्य तक पहुंच की आवश्यकता होती है जिसने पुनः प्रयास करने के लिए वादा वापस कर दिया है।

वादे वास्तव में इस अर्थशास्त्र को लागू करते हैं। आप एक वादा कर सकते हैं, जो कुछ मूल्य के साथ हल करता है:

   const numberPromise = new Promise((resolve) => {
    resolve(5);
});

numberPromise.then(value => console.log(value));
// will simply print 5

लेकिन एक और मूल्य के साथ फिर से वादा को हल करने का प्रयास विफल हो जाएगा। वादा समारोह को पारित किए गए पहले मान के साथ वादा हमेशा हल किया जाता है और इसे आगे की कॉल को अनदेखा करता है:

    const numberPromise = new Promise((resolve) => {
    resolve(5);
    resolve(10);
});

numberPromise.then(value => console.log(value));
// still prints only 5

इसके विपरीत, अवलोकन आपको कई मानों को हल करने की अनुमति देता है (या, जैसा कि हम कहते हैं, "emit")। यहां बताया गया है कि यह कैसा दिखाई देगा:

    const numberObservable = new Observable((observer) => {
    observer.next(5);
    observer.next(10);
});

numberObservable.subscribe(value => console.log(value));
// prints 5 and 10

ध्यान दें कि सिंटैक्स कैसा है - हमने वादे को अवलोकन करने के लिए स्विच किया है, पर्यवेक्षक.नेक्स्ट कॉल के साथ हल करने के फ़ंक्शन को प्रतिस्थापित किया है और उसके बाद सब्सक्राइब किया गया है, जो बहुत समान व्यवहार करता है।


हालांकि यह उत्तर देर हो चुकी है, मैंने नीचे दिए गए मतभेदों का सारांश दिया है,

नमूदार:

  1. अवलोकन करने योग्य एक ऐसा function है an observer लेता है और एक function Observer: an object with next, error. देता है function Observer: an object with next, error.
  2. पर्यवेक्षक अपनी डेटा स्ट्रीम की subscribe/unsubscribe करने, पर्यवेक्षक को अगले मूल्य उत्सर्जित करने, पर्यवेक्षक को errors बारे में सूचित करने और stream completion बारे में पर्यवेक्षक को सूचित stream completion
  3. पर्यवेक्षक function to handle next value , त्रुटियों और स्ट्रीम के अंत (ui घटनाओं, http प्रतिक्रियाओं, वेब सॉकेट के साथ डेटा) function to handle next value एक function to handle next value प्रदान करता है।
  4. समय के साथ multiple values साथ काम करता है
  5. यह cancel-able/retry-able और ऑपरेटर का समर्थन करता है जैसे map,filter,reduce आदि।
  6. एक अवलोकन करने योग्य हो सकता है - Observable.create() - रिटर्न रिटर्न जो Observer Observable.from() - पर एक आवेदक या पुनरावर्तनीय रूपांतरित करता है - Observable Observable.fromEvent() - एक घटना को अवलोकन में बदल देता है - Observable.fromPromise() - एक वादा को अवलोकन में परिवर्तित करता है - Observable.range() - विशिष्ट सीमा में पूर्णांक का अनुक्रम देता है

वादा :

  1. एक वादा एक कार्य का प्रतिनिधित्व करता है जो भविष्य में खत्म हो जाएगा;

  2. वादे resolved by a value हो जाते हैं;

  3. अपवादों से वादा खारिज कर दिया;

  4. cancellable नहीं है और यह a single value देता a single value

  5. एक वादा एक समारोह का खुलासा करता है (then)

    - फिर एक नया promise देता है;

    - उस के attachment के लिए अनुमति state आधार पर निष्पादित की जाएगी;

    - handlers को order attached में निष्पादित करने की guaranteed है;


वचन और पर्यवेक्षण दोनों जावास्क्रिप्ट में एसिंक्रोनस कार्यक्षमताओं के साथ काम करने में हमारी सहायता करेंगे। वे कई मामलों में बहुत समान हैं, हालांकि, दोनों के बीच कुछ अंतर भी हैं, वादे वे मान हैं जो http कॉल जैसे asynchronous तरीके से हल हो जाएंगे। दूसरी तरफ, अवलोकन अतुल्यकालिक घटनाओं के अनुक्रम के साथ सौदा करते हैं । मुख्य मतभेद नीचे दिए गए हैं:

पक्का वादा:

  • एक पाइप लाइन है
  • आमतौर पर केवल एसिंक डेटा रिटर्न के साथ उपयोग करते हैं
  • रद्द करना आसान नहीं है

नमूदार:

  • रद्द करने योग्य हैं
  • प्रकृति द्वारा प्रत्याशित हैं जैसे कि पुनः प्रयास करें और पुनः प्रयास करें
  • एकाधिक पाइप लाइनों में स्ट्रीम डेटा
  • नक्शा, फ़िल्टर इत्यादि जैसे सरणी जैसे ऑपरेशन
  • घटनाओं जैसे अन्य स्रोतों से बनाया जा सकता है
  • वे कार्य हैं, जिन्हें बाद में सब्सक्राइब किया जा सकता है

इसके अलावा, मैंने अंतर को अंतर दिखाने के लिए नीचे आपके लिए ग्राफिकल छवि बनाई है:


मैं एक चित्र लड़का हूं, यह अन्य उत्तरों में गायब था:


! वादे बनाम पर्यवेक्षक

  • पक्का वादा:
    1. एक एकल मूल्य देता है
    2. रद्द करने योग्य नहीं
    3. कोशिश / पकड़ और async / प्रतीक्षा के साथ अधिक पठनीय कोड
  • नमूदार
    1. समय के साथ कई मूल्यों के साथ काम करता है
    2. रद्द करने योग्य
    3. मानचित्र, फ़िल्टर, कम करने और समान ऑपरेटर का समर्थन करता है
    4. प्रतिक्रियाशील एक्सटेंशन का उपयोग करें (आरएक्सजेएस)
    5. एक सरणी जिसका आइटम समय के साथ असीमित रूप से आता है

मैंने अभी एक ऐसे मुद्दे से निपटाया है जहां वादा सबसे अच्छा समाधान था, और मैं इसे इस प्रश्न में किसी भी व्यक्ति के लिए यहां साझा करने के लिए साझा कर रहा हूं, यह उपयोगी है (यह वही जवाब था जो मैं पहले की तलाश में था):

एक कोणीय 2 प्रोजेक्ट में मेरे पास एक ऐसी सेवा है जो कुछ पैरामीटर लेती है और एक फॉर्म पर ड्रॉप डाउन मेनू को पॉप्युलेट करने के लिए एक मूल्य सूची देता है। जब फॉर्म घटक प्रारंभ होता है, तो मुझे कई अलग-अलग ड्रॉपडाउन मेनू को परिभाषित करने के लिए अलग-अलग पैरामीटर के साथ एक ही सेवा को कई बार कॉल करने की आवश्यकता होती है, हालांकि यदि मैं सेवा को कॉल करने के लिए सभी चरों को कतारबद्ध करता हूं, तो केवल अंतिम सफल होता है और बाकी त्रुटि बाहर। डेटाबेस से प्राप्त सेवा केवल एक ही समय में एक अनुरोध को संभाल सकती है।

सभी ड्रॉपडाउन मेनू चरों को सफलतापूर्वक पॉप्युलेट करने का एकमात्र तरीका सेवा को इस तरह से कॉल करना था कि अंतिम अनुरोध समाप्त होने तक एक नए अनुरोध को संसाधित होने से रोका गया, और वादा / .then तंत्र ने समस्या को हल किया।

  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;
          })  }

मैंने घटक में कार्यों को परिभाषित किया, और फिर ngOnInit में प्रारंभिक DropDowns () कहा जाता है।

FetchValueList फ़ंक्शन एक वादा करता है, इसलिए पहली कॉल पहली सूची को पास करती है कोड और जब वादा हल हो जाता है, तो वापसी मान .then ब्लॉक में डेटा वैरिएबल में होता है जहां हम इसे इस पर असाइन कर सकते हैं। फर्स्टवेललिस्ट चर। चूंकि फ़ंक्शन डेटा लौटा चुका है, हम जानते हैं कि सेवा समाप्त हो गई है और दूसरी सूची कोड के साथ फिर से कॉल करना सुरक्षित है, वापसी मूल्य अगले डेटा में डेटा वैरिएबल में है। तो ब्लॉक और हम इसे इस .secondValList चर को असाइन करते हैं।

हम इसे सभी चरों को पॉप्युलेट करने के लिए जितनी बार आवश्यक हो सकते हैं, और अंतिम कोड ब्लॉक पर हम केवल रिटर्न स्टेटमेंट को छोड़ देते हैं और ब्लॉक समाप्त हो जाता है।

यह एक बहुत ही विशिष्ट उपयोग मामला है जहां हमारे पास एक ही सेवा है जिसे घटक शुरू करने के रूप में कई बार बुलाया जाना चाहिए, और जहां सेवा को अपने fetch को पूरा करना है और उसे फिर से कॉल करने से पहले एक मूल्य वापस करना है, लेकिन इस मामले में, वादा / .then विधि आदर्श थी।


उत्तर में अवलोकन के अवलोकन का एक नकारात्मक पक्ष है। वादे ES7 async / प्रतीक्षा कार्यों का उपयोग करने की अनुमति देते हैं। उनके साथ आप एसिंक्रोनस कोड लिख सकते हैं जैसे कि यह एक सिंक्रोनस फ़ंक्शन कॉल होगा, इसलिए आपको अब कॉलबैक की आवश्यकता नहीं है। पर्यवेक्षकों के लिए ऐसा करने की एकमात्र संभावना है, उन्हें वादा में परिवर्तित करना है। लेकिन जब आप उन्हें वादे में परिवर्तित करते हैं, तो आपके पास केवल एक वापसी मूल्य हो सकता है:

async function getData(){
    const data = await observable.first().toPromise();
    //do stuff with 'data' (no callback function needed)
}

आगे पढ़ने: मैं एक आरएक्स पर्यवेक्षक पर `इंतजार कैसे कर सकता हूं?





angular-observable