Sözü Gözlenebilirliğe Dönüştür


214

Başımı gözlenebilirlerin etrafına sarmaya çalışıyorum. Gözlenebilirlerin geliştirme ve okunabilirlik sorunlarını çözme şeklini seviyorum. Okuduğum gibi, faydalar çok büyük.

HTTP ve koleksiyonlardaki gözlemlenebilirler basit görünüyor. Böyle bir şeyi nasıl gözlemlenebilir desene dönüştürebilirim.

Bu, kimlik doğrulaması sağlamak için hizmet bileşenimden. Bu veri, hata ve tamamlama işleyicileri desteği ile Angular2 diğer HTTP hizmetleri gibi çalışmasını tercih ederim.

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

Burada herhangi bir yardım çok takdir edilecektir. Sahip olduğum tek alternatif çözüm EventEmitters yaratmaktı . Ama sanırım bu, hizmetler bölümünde bir şeyler yapmanın korkunç bir yolu

Yanıtlar:


319

RxJS 6.0.0 kullanıyorsanız:

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

9
6.3.3 kullanarak, fromyöntem gözlemlenebilir döndürür ancak aboneliklere değer vaat ediyor. :(
Laxmikant Dange

1
Bu cevap RXJS 6+ için ilişkilidir. Ben operators"sezgi" üzerinden ithalat denedim - yanılmışım.
VSO

119

bunu dene:

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 */);

buradan fromPromise operatörüne tam bir referans bulabilirsiniz .


47
import 'rxjs/add/observable/fromPromise';
Simon Briggs

16
import { Observable } from "rxjs/Observable"; :)
Luckylooke

41

1 Doğrudan Yürütme / Dönüştürme

fromÖnceden oluşturulmuş bir sözü doğrudan gözlemlenebilir hale dönüştürmek için kullanın .

import { from } from 'rxjs';

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

observable$abonelere vaat edilen değeri etkili bir şekilde tekrar eden sıcak bir gözlemlenebilir olacaktır .

Vaat edilen kuruluş yürütülür veya gözlemlenebilir durum yaratıldığında zaten çözülmüştür. Eğer iç vaat çözülmüşse, gözlemlenebilir kişiye yeni bir abone derhal değerini alacaktır.

Her Abonelikte 2 Ertelenmiş Yürütme

Kullan deferbir gözlemlenebilir bir söz oluşturulmasını ve dönüşüm erteleme girdi olarak bir söz fabrika fonksiyonu ile.

import { defer } from 'rxjs';

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

observable$Bir olacaktır soğuk gözlemlenebilir .

Farkı fromyani deferbir abone için bekler ve ancak o zaman verilen söz fabrika işlevini çağırarak yeni bir söz yaratır. Bu, gözlemlenebilir bir oluşturmak istediğinizde, ancak iç vaatlerin hemen yerine getirilmesini istemediğinizde kullanışlıdır. İç vaat ancak biri gözlenebilir olana abone olduğunda yürütülür. Her abone kendi yeni gözlemlenebilirliğini alacaktır.

3 Birçok Operatör Doğrudan Verilen Sözleri Kabul Ediyor

Birleştirmek çoğu RxJS operatörleri (örneğin merge, concat, forkJoin, combineLatest...) ya da (örn gözlenebilirleri dönüşümü switchMap, mergeMap, concatMap, catchError...) doğrudan sözlerini kabul edin. Zaten bunlardan birini kullanıyorsanız from, önce bir söz vermek için kullanmanız gerekmez (ancak soğuk bir gözlemlenebilir oluşturmak için yine de kullanmanız gerekebilir defer).

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

Kontrol belgeleri veya uygulama kullandığınız operatör kabul görmek için ObservableInputya 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>;

Bir örnek arasındaki fromve deferbir örnek arasındaki fark : 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
Bu farkın sermaye olduğunu düşünüyorum, belirttiğiniz için teşekkürler.
Starscream

1

Ayrıca bir Konu kullanabilir ve sonraki () işlevini vaatlerden tetikleyebilirsiniz . Aşağıdaki örneğe bakın:

Aşağıdaki gibi kod ekleyin (hizmeti kullandım)

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

  }
}

Aşağıdaki gibi Bileşenden Kullanıcı Oluştur

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


Denekler düşük seviyeli makinelerdir. Uzattığınız durumlar dışında konuları kullanmayın rxjs.
polkovnikov.ph

Sadece bir çözüm veriyorum.
Shivang Gupta

Bunu new Observable(observer => { ... observer.next() ... })uygulamak için en azından bir yol göstermiş olabilirsiniz . Mevcut iyi bilinen fonksiyonun yeniden uygulanması olsa da, soruyu doğrudan cevaplayacaktır ve okuyucular için zararlı olmayacaktır.
polkovnikov.ph


0

Bir Observable'ı gözlemciye döndürmek için söz işlevselliğinin etrafına bir sarıcı ekleyebilirsiniz.

  • Defer () operatörünü kullanarak Tembel bir Gözlemlenebilir oluşturma Oluşturma , yalnızca Gözlemci abone olduğunda Gözlemlenebilir oluşturmanızı sağlar.
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);
   }
)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.