कन्वर्ट प्रॉमिस टू ऑब्जर्वेबल


214

मैं अपने सिर को वेधशालाओं के चारों ओर लपेटने की कोशिश कर रहा हूं। मैं प्रेक्षकों के विकास और पठनीयता के मुद्दों को हल करने के तरीके से प्यार करता हूं। जैसा कि मैंने पढ़ा है, लाभ काफी हैं।

HTTP और संग्रह पर वेधशालाएं सीधे आगे लगती हैं। मैं इस तरह के कुछ को कैसे अवलोकन पैटर्न में बदल सकता हूं।

यह प्रमाणीकरण प्रदान करने के लिए मेरे सेवा घटक से है। मैं डेटा, त्रुटि और पूर्ण हैंडलर के समर्थन के साथ Angular2 में अन्य HTTP सेवाओं की तरह काम करना पसंद करूंगा।

firebase.auth().createUserWithEmailAndPassword(email, password)
  .then(function(firebaseUser) {
    // do something to update your UI component
    // pass user object to UI component
  })
  .catch(function(error) {
    // Handle Errors here.
    var errorCode = error.code;
    var errorMessage = error.message;
    // ...
  });

यहाँ किसी भी मदद की बहुत सराहना की जाएगी। एकमात्र वैकल्पिक समाधान मेरे पास था बनाने के लिए EventEmitter। लेकिन मुझे लगता है कि सेवा सेक्शन में चीजों को करने का एक भयानक तरीका है

जवाबों:


318

यदि आप RxJS 6.0.0 का उपयोग कर रहे हैं:

import { from } from 'rxjs';
const observable = from(promise);

9
6.3.3 का उपयोग करते हुए, fromविधि अवलोकन योग्य है लेकिन यह सदस्यता के मूल्य के रूप में वादा भेज रही है। :(
लक्ष्मीकांत डांगे

1
यह उत्तर RXJS 6+ के लिए संक्षिप्त है। मैंने operators"अंतर्ज्ञान" के माध्यम से आयात करने की कोशिश की - मैं गलत था।
वीएसओ

119

इसे इस्तेमाल करे:

import 'rxjs/add/observable/fromPromise';
import { Observable } from "rxjs/Observable";

const subscription = Observable.fromPromise(
    firebase.auth().createUserWithEmailAndPassword(email, password)
);
subscription.subscribe(firebaseUser => /* Do anything with data received */,
                       error => /* Handle error here */);

आप यहाँ से ऑपरेटर ऑपरेटर से पूरा संदर्भ पा सकते हैं ।


47
import 'rxjs/add/observable/fromPromise';
साइमन ब्रिग्स

16
import { Observable } from "rxjs/Observable"; :)
लकीलोके

41

1 प्रत्यक्ष निष्पादन / रूपांतरण

fromपहले से बनाए गए वादे को सीधे पालन योग्य में बदलने के लिए उपयोग करें ।

import { from } from 'rxjs';

// getPromise() will only be called once
const observable$ = from(getPromise());

observable$एक गर्म अवलोकन होगा जो ग्राहकों को वादों के मूल्य को प्रभावी ढंग से दोहराता है।

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

प्रत्येक सदस्यता पर 2 आस्थगित निष्पादन

deferएक वादा निर्माण कार्य के साथ प्रयोग के रूप में निर्माण और एक वादे के लिए एक रूपांतरण को स्थगित करने के लिए इनपुट।

import { defer } from 'rxjs';

// getPromise() will be called every time someone subscribes to the observable$
const observable$ = defer(() => getPromise());

observable$एक ठंडा अवलोकन होगा

अंतर यह fromहै कि deferएक ग्राहक की प्रतीक्षा करता है और उसके बाद ही दिए गए वादे के फ़ैक्टरी फ़ंक्शन को कॉल करके एक नया वादा करता है। यह तब उपयोगी होता है जब आप एक अवलोकनीय बनाना चाहते हैं, लेकिन भीतर के वचन को तुरंत क्रियान्वित नहीं करना चाहते हैं। आंतरिक वादे को तभी क्रियान्वित किया जाएगा जब कोई व्यक्ति अवलोकन योग्य हो। प्रत्येक ग्राहक को अपने स्वयं के नए अवलोकन भी प्राप्त होंगे।

3 कई ऑपरेटरों सीधे वादा वादा करता हूँ

अधिकांश RxJS ऑपरेटरों कि गठबंधन (जैसे merge, concat, forkJoin, combineLatest...) या observables को बदलने (जैसे switchMap, mergeMap, concatMap, catchError...) वादों सीधे स्वीकार करते हैं। यदि आप उनमें से किसी एक का उपयोग कर रहे हैं, तो आपको fromपहले वादे को पूरा करने के लिए उपयोग करने की आवश्यकता नहीं है (लेकिन एक ठंडा अवलोकन बनाने के लिए जिसे आपको अभी भी उपयोग करना पड़ सकता है defer)।

// Execute two promises simultaneously
forkJoin(getPromise(1), getPromise(2)).pipe(
  switchMap(([v1, v2]) => v1.getPromise(v2)) // map to nested Promise
)

चेक प्रलेखन या कार्यान्वयन ऑपरेटर आप उपयोग कर रहे स्वीकार करता है देखने के लिए ObservableInputया SubscribableOrPromise

type ObservableInput<T> = SubscribableOrPromise<T> | ArrayLike<T> | Iterable<T>;
// Note the PromiseLike ----------------------------------------------------v
type SubscribableOrPromise<T> = Subscribable<T> | Subscribable<never> | PromiseLike<T> | InteropObservable<T>;

एक उदाहरण में fromऔर बीच का अंतर defer: https://stackblitz.com/edit/rxjs-6rb7vf

const getPromise = val => new Promise(resolve => {
  console.log('Promise created for', val);
  setTimeout(() => resolve(`Promise Resolved: ${val}`), 5000);
});

// the execution of getPromise('FROM') starts here, when you create the promise inside from
const fromPromise$ = from(getPromise('FROM'));
const deferPromise$ = defer(() => getPromise('DEFER'));

fromPromise$.subscribe(console.log);
// the execution of getPromise('DEFER') starts here, when you subscribe to deferPromise$
deferPromise$.subscribe(console.log);

4
मुझे लगता है कि यह अंतर पूंजी है, इसे इंगित करने के लिए धन्यवाद।
स्टार्सक्रीम

1

आप एक विषय का उपयोग भी कर सकते हैं और वादे से इसके अगले () फ़ंक्शन को ट्रिगर कर सकते हैं । नीचे नमूना देखें:

नीचे जैसा कोड जोड़ें (मैंने सेवा का उपयोग किया)

class UserService {
  private createUserSubject: Subject < any > ;

  createUserWithEmailAndPassword() {
    if (this.createUserSubject) {
      return this.createUserSubject;
    } else {
      this.createUserSubject = new Subject < any > ();
      firebase.auth().createUserWithEmailAndPassword(email,
          password)
        .then(function(firebaseUser) {
          // do something to update your UI component
          // pass user object to UI component
          this.createUserSubject.next(firebaseUser);
        })
        .catch(function(error) {
          // Handle Errors here.
          var errorCode = error.code;
          var errorMessage = error.message;
          this.createUserSubject.error(error);
          // ...
        });
    }

  }
}

नीचे से घटक की तरह उपयोगकर्ता बनाएँ

class UserComponent {
  constructor(private userService: UserService) {
    this.userService.createUserWithEmailAndPassword().subscribe(user => console.log(user), error => console.log(error);
    }
  }


विषय निम्न-स्तरीय मशीनरी हैं। जब आप विस्तार कर रहे हों, तब मामलों को छोड़कर, विषयों का उपयोग न करें rxjs
polkovnikov.ph

मैं सिर्फ एक समाधान दे रहा हूं।
शिवांग गुप्ता

new Observable(observer => { ... observer.next() ... })इसे लागू करने के लिए आपके पास कम से कम रास्ता दिखाया जा सकता है । भले ही यह मौजूदा प्रसिद्ध समारोह का पुन: कार्यान्वयन होगा, यह सीधे सवाल का जवाब देगा और पाठकों के लिए हानिकारक नहीं होगा।
polkovnikov.ph


0

ऑब्जर्वर को ऑब्जर्वर में वापस करने के लिए आप वादा कार्यक्षमता के आसपास एक रैपर जोड़ सकते हैं।

  • डेफर () ऑपरेटर का उपयोग करके एक आलसी ऑब्जर्वेबल का निर्माण करना जो आपको ऑब्जर्वर को केवल तभी बनाने की अनुमति देता है जब ऑब्जर्वर सब्सक्राइब करता है।
import { of, Observable, defer } from 'rxjs'; 
import { map } from 'rxjs/operators';


function getTodos$(): Observable<any> {
  return defer(()=>{
    return fetch('https://jsonplaceholder.typicode.com/todos/1')
      .then(response => response.json())
      .then(json => {
        return json;
      })
  });
}

getTodos$().
 subscribe(
   (next)=>{
     console.log('Data is:', next);
   }
)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.