Geben Sie ein leeres Observable zurück

165

Die Funktion more()soll eine Observablevon einer get-Anfrage zurückgeben

export class Collection{

    public more = (): Observable<Response> => {
       if (this.hasMore()) {

         return this.fetch();
       }
       else{
         // return empty observable
       }
    }

    private fetch = (): Observable<Response> => {
       return this.http.get('some-url').map(
          (res) => {
              return res.json();
          }
       );
    }
}

In diesem Fall kann ich eine Anfrage nur dann stellen, wenn sie hasMore()wahr ist. Andernfalls wird ein subscribe()Funktionsfehler angezeigt subscribe is not defined. Wie kann ich eine leere Observable zurückgeben?

this.collection.more().subscribe(
   (res) =>{
       console.log(res);
   },
   (err) =>{
       console.log(err);
   }
)

Aktualisieren

In RXJS 6

import { EMPTY } from 'rxjs'

return EMPTY; 
Murhaf Sousli
quelle

Antworten:

129

Für Typoskript können Sie generische Parameter Ihres leeren Observable wie folgt angeben:

import 'rxjs/add/observable/empty' 

Observable.empty<Response>();
Andrei Petrov
quelle
26
Dies sollte jetzt sein import "EmptyObservable" from "rxjs/observable/EmptyObservable";, dann new EmptyObservable<Response>();.
86

Mit der neuen Syntax von RxJS 5.5+ wird dies wie folgt:

// RxJS 6
import { empty, of } from "rxjs";

// rxjs 5.5+ (<6)
import { empty } from "rxjs/observable/empty";
import { of } from "rxjs/observable/of";

empty();
of({});

Nur eine Sache, die Sie beachten sollten, empty()vervollständigt das Observable, sodass es nicht nextin Ihrem Stream ausgelöst wird , sondern nur abgeschlossen wird. Wenn Sie zum Beispiel haben tap, werden sie möglicherweise nicht wie gewünscht ausgelöst (siehe ein Beispiel unten).

Während of({})erstellt ein Observableund emittiert als nächstes mit einem Wert von {}und vervollständigt dann das Observable.

Z.B:

empty().pipe(
    tap(() => console.warn("i will not reach here, as i am complete"))
).subscribe();

of({}).pipe(
    tap(() => console.warn("i will reach here and complete"))
).subscribe();
Stephen Lautier
quelle
1
of('foo')emittiert und vervollständigt das Observable sofort. rxviz.com/v/0oqMVW1o
SimplGy
@ SimplGy ja du bist richtig, mein schlechtes für die Verwendung take(1)entfernt für eine bessere Antwort. @MatthijsWessels, ja und nein, haben dies gerade getestet und wenn Sie dies tun, of()werden Sie ein vollständiges Observable ohne Emission zurückgebennext
Stephen Lautier
leer ist jetzt veraltet, verwenden Sie stattdessen LEER (wird als Konstante anstelle einer Methode verwendet, siehe Antwort von Simon_Weaver).
EriF89
Bitte beachten Sie, dass () keinen Wert ausgibt. Wenn Sie einen möchten, sollten Sie einen beliebigen Wert angeben, auch undefiniert oder null ist dafür in Ordnung: of (null) gibt den Wert aus (und verarbeitet mit Tap / Subscribe-Methoden), während of () dies nicht tut.
Maxim Georgievskiy
51

RxJS6 (ohne Kompatibilitätspaket installiert)

Es gibt jetzt eine EMPTYKonstante und eine emptyFunktion.

  import { Observable, empty, of } from 'rxjs';

  var delay = empty().pipe(delay(1000));     
  var delay2 = EMPTY.pipe(delay(1000));

Observable.empty() existiert nicht mehr.

Simon_Weaver
quelle
Wenn Sie bereits einen Konflikt wie eine empty()Funktion haben, können Sie import { empty as rxEmpty }oder sagen import { empty as _empty }und dann tun rxEmpty()oder _empty(). Natürlich ist das eine ziemlich ungewöhnliche Sache und ich empfehle sie nicht wirklich, aber ich bin sicher, dass ich nicht der einzige bin, der überrascht war, dass RxJS der Meinung ist, dass es sich lohnt, Funktionen wie zu importierenof und emptyin meinen Namespace zu !
Simon_Weaver
1
Vorsicht bei der Verwendung von Angular, da es auch etwas gibt, import { EMPTY } from "@angular/core/src/render3/definition";das absolut nicht das ist, was Sie wollen. Wenn Sie also seltsame Fehler erhalten, stellen Sie sicher, dass Sie diese nicht versehentlich importieren.
Simon_Weaver
Observable.empty() tatsächlich existiert noch, ist aber zugunsten von veraltet EMPTY.
Alexander Abakumov
39

In meinem Fall mit Angular2 und rxjs funktionierte es mit:

import {EmptyObservable} from 'rxjs/observable/EmptyObservable';
...
return new EmptyObservable();
...
Marcel Tinner
quelle
7
schließen Sie es mit einimport {EmptyObservable} from 'rxjs/observable/EmptyObservable';
Kildareflare
Wenn ein Fehler wie dieser angezeigt wird, muss ich irgendetwas in der Systemkonfiguration konfigurieren? Nicht behandelte Ablehnung von Versprechungen: (SystemJS) XHR-Fehler (404 nicht gefunden) Laden von localhost: 9190 / node_modules / rxjs / Observable / EmptyObservable.js Fehler: XHR-Fehler (404 nicht gefunden) Laden von localhost: 9190 / node_modules / rxjs / Observable / EmptyObservable. js
user630209
29

Ja, es gibt einen leeren Operator

Rx.Observable.empty();

Für Typoskript können Sie Folgendes verwenden from:

Rx.Observable<Response>.from([])
Toan Nguyen
quelle
Ich bekomme Rx.Observable<{}>ist nicht zuordenbar Observable<Response>, ich habe es versucht, Rx.Observable<Response>.empty()aber es hat nicht funktioniert
Murhaf Sousli
Ich habe den Rückgabetyp in geändert Observable<any>und es hat funktioniert, danke Kumpel.
Murhaf Sousli
2
Es sollte Rx.Observable.from([])ohne sein <Response>. Andernfalls wird der Fehler "Ausdruck erwartet" angezeigt.
Andriy Tolstoy
2
Sie können auch verwenden Rx.Observable.of([]).
Andriy Tolstoy
1
@AndriyTolstoy Ich bin nicht sicher, ob dies gleichwertig ist. In Observable.of([])wird ein Wert ausgegeben ( []) und dann wird der Stream abgeschlossen. Wenn Observable.from([])kein Wert ausgegeben wird, wird der Stream sofort abgeschlossen.
Pac0
23

Verschiedene Möglichkeiten, um ein leeres Observable zu erstellen:

Sie unterscheiden sich nur, wie Sie es wollen weiter verwenden (welche Ereignisse es nach emittieren: next, completeoder do nothing) , zB:

  • Observable.never() - gibt keine Ereignisse aus und endet nie.
  • Observable.empty()- emittiert nur complete.
  • Observable.of({})- gibt beide aus nextund complete(leeres Objektliteral als Beispiel übergeben).

Verwenden Sie es für Ihre genauen Bedürfnisse)

Andrii Verbytskyi
quelle
12

Sie können beispielsweise Observable.of (empty_variable) zurückgeben

Observable.of('');

// or
Observable.of({});

// etc
Chybie
quelle
2

Oder Sie können versuchen , ignoreElements()als auch

Tuong Le
quelle
1

RxJS 6

Sie können auch von der Funktion wie unten verwenden:

return from<string>([""]);

nach dem Import:

import {from} from 'rxjs';
Nour
quelle
2
Dadurch wird ein Observable erstellt, das ein Element (eine leere Zeichenfolge) bereitstellt, sodass es nicht wie eine richtige Antwort auf diese spezielle Frage aussieht.
BrunoJCM
1

Kam hier mit einer ähnlichen Frage, funktionierte das oben genannte für mich nicht in: "rxjs": "^6.0.0"um ein Observable zu generieren, das keine Daten ausgibt, die ich tun musste:

import {Observable,empty} from 'rxjs';
class ActivatedRouteStub {
  params: Observable<any> = empty();
}
Ruf an bei
quelle
0

Versuche dies

export class Collection{
public more (): Observable<Response> {
   if (this.hasMore()) {
     return this.fetch();
   }
   else{
     return this.returnEmpty(); 
   }            
  }
public returnEmpty(): any {
    let subscription = source.subscribe(
      function (x) {
       console.log('Next: %s', x);
    },
    function (err) {
       console.log('Error: %s', err);
    },
    function () {
       console.log('Completed');
    });
    }
  }
let source = Observable.empty();
Jorawar Singh
quelle