Restituisce un osservabile vuoto


167

La funzione more()dovrebbe restituire un Observableda una richiesta get

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 questo caso posso solo fare una richiesta se hasMore()è vero, altrimenti ricevo un errore sulla subscribe()funzione subscribe is not defined, come posso restituire un osservabile vuoto?

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

Aggiornare

In RXJS 6

import { EMPTY } from 'rxjs'

return EMPTY; 

Risposte:


130

Per dattiloscritto puoi specificare i parametri generici del tuo osservabile vuoto in questo modo:

import 'rxjs/add/observable/empty' 

Observable.empty<Response>();

26
Questo dovrebbe essere ora import "EmptyObservable" from "rxjs/observable/EmptyObservable";, quindi new EmptyObservable<Response>();.

87

Con la nuova sintassi di RxJS 5.5+, questo diventa il seguente:

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

Solo una cosa da tenere a mente, empty()completa l'osservabile, quindi non si innescherà nextnel tuo stream, ma solo completerà. Quindi, se hai, ad esempio, tappotrebbero non attivarsi come desideri (vedi un esempio di seguito).

Considerando che of({})crea un Observableed emette il successivo con un valore di {}e quindi completa il Observable.

Per esempio:

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


1
of('foo')emette e completa immediatamente l'osservabile. rxviz.com/v/0oqMVW1o
Semplicemente

@SimplGy sì hai ragione, il mio male per l'utilizzo take(1)rimosso per una risposta migliore. @MatthijsWessels, sì e no, ho appena provato questo ora e se lo fai of()restituirà un osservabile completo senza emetterenext
Stephen Lautier

vuoto è ora deprecato, utilizzare invece EMPTY (utilizzato come costante anziché come metodo, vedere la risposta di Simon_Weaver).
EriF89,

Tieni presente che () non emette alcun valore. Se ne vuoi uno, dovresti fornire qualsiasi valore, anche undefined o null è ok per questo: of (null) emette il valore (e elabora con i metodi tap / iscriviti), mentre of () no.
Maxim Georgievskiy,

51

RxJS6 (senza pacchetto di compatibilità installato)

Ora c'è una EMPTYcostante e una emptyfunzione.

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

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

Observable.empty() non esiste più.



Se hai già un conflitto come una empty()funzione, puoi dire import { empty as rxEmpty }o import { empty as _empty }e poi fare rxEmpty()o _empty(). Ovviamente è una cosa piuttosto non standard da fare e in realtà non lo sto raccomandando, ma sono sicuro di non essere l'unico ad essere sorpreso che RxJS pensi che sia degno di importare funzioni come ofe emptynel mio spazio dei nomi!
Simon_Weaver,

1
fai attenzione se usi Angular perché c'è anche quello import { EMPTY } from "@angular/core/src/render3/definition";che non è esattamente quello che vuoi. Quindi, se ricevi errori strani, assicurati di non importarli per errore.
Simon_Weaver,

Observable.empty()in realtà esiste ancora ma è deprecato a favore di EMPTY.
Alexander Abakumov,

39

Nel mio caso con Angular2 e rxjs, ha funzionato con:

import {EmptyObservable} from 'rxjs/observable/EmptyObservable';
...
return new EmptyObservable();
...

7
import {EmptyObservable} from 'rxjs/observable/EmptyObservable';
includilo

ricevendo un errore del genere, devo configurare qualcosa in configurazione di sistema? Rifiuto promessa non gestita: (SystemJS) Errore XHR (404 non trovato) caricamento localhost: 9190 / node_modules / rxjs / Observable / EmptyObservable.js Errore: errore XHR (404 non trovato) caricamento localhost: 9190 / node_modules / rxjs / Observable / EmptyObservable. js
user630209

29

Sì, c'è un operatore vuoto

Rx.Observable.empty();

Per dattiloscritto, puoi usare from:

Rx.Observable<Response>.from([])

Ricevo che Rx.Observable<{}>non è assegnabile a Observable<Response>, ci ho provato Rx.Observable<Response>.empty()ma non ha funzionato
Murhaf Sousli

Ho cambiato il tipo di ritorno in Observable<any>e ha funzionato, grazie amico.
Murhaf Sousli,

2
Dovrebbe essere Rx.Observable.from([])senza <Response>. In caso contrario, viene visualizzato un errore "espressione prevista".
Andriy Tolstoy,

2
Puoi anche usare Rx.Observable.of([]).
Andriy Tolstoy,

1
@AndriyTolstoy Non sono sicuro che questo sia equivalente. In Observable.of([]), viene emesso un valore ( []) e quindi lo stream viene completato. Con Observable.from([]), non viene emesso alcun valore, il flusso si completa immediatamente.
Pac0,

24

Diversi modi per creare un osservabile vuoto:

Hanno appena differiscono su come avete intenzione di usarlo ulteriormente (quali eventi emetterà dopo: next, completeo do nothing) ad esempio:

  • Observable.never() - non emette eventi e non finisce mai.
  • Observable.empty()- emette solo complete.
  • Observable.of({})- emette entrambi nexte complete(letterale oggetto vuoto passato come esempio).

Usalo sulle tue esatte esigenze)


13

È possibile restituire Observable.of (empty_variable), ad esempio

Observable.of('');

// or
Observable.of({});

// etc


1

RxJS 6

puoi usare anche dalla funzione come sotto:

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

dopo l'importazione:

import {from} from 'rxjs';

2
Questo creerà un osservabile che fornirà un elemento (una stringa vuota), quindi non sembra una risposta adeguata a questa domanda specifica.
BrunoJCM,

1

Sono venuto qui con una domanda simile, quanto sopra non ha funzionato per me "rxjs": "^6.0.0"in:, al fine di generare un osservabile che non emette dati che dovevo fare:

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

0

Prova questo

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();
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.