Kembalikan Observable yang kosong

167

Fungsi more()ini seharusnya mengembalikan sebuah Observabledari permintaan dapatkan

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

Dalam hal ini saya hanya bisa melakukan permintaan jika hasMore()benar, kalau tidak saya mendapatkan kesalahan pada subscribe()fungsi subscribe is not defined, bagaimana saya bisa mengembalikan yang kosong diamati?

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

Memperbarui

Di RXJS 6

import { EMPTY } from 'rxjs'

return EMPTY; 
Murhaf Sousli
sumber

Jawaban:

130

Untuk naskah, Anda dapat menentukan param generik dari kosong Anda diamati seperti ini:

import 'rxjs/add/observable/empty' 

Observable.empty<Response>();
Andrei Petrov
sumber
26
Ini sekarang harus import "EmptyObservable" from "rxjs/observable/EmptyObservable";, kemudian new EmptyObservable<Response>();.
87

Dengan sintaks baru RxJS 5.5+, ini menjadi sebagai berikut:

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

Hanya satu hal yang perlu diingat, empty()selesaikan yang dapat diamati, sehingga tidak akan memicu nextdalam aliran Anda, tetapi hanya selesai. Jadi, jika Anda memiliki, misalnya, tapmereka mungkin tidak mendapatkan pemicu seperti yang Anda inginkan (lihat contoh di bawah).

Sedangkan of({})menciptakan Observabledan memancarkan berikutnya dengan nilai {}dan kemudian melengkapi Observable.

Misalnya:

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
sumber
2
Anda juga bisa of()percaya saja
Matthijs Wessels
1
of('foo')Apakah memancarkan dan menyelesaikan diamati dengan segera. rxviz.com/v/0oqMVW1o
SimplGy
@ Sederhana Ya Anda benar, salah saya untuk menggunakan take(1)dihapus untuk jawaban yang lebih baik. @MatthijsWessels, ya dan tidak, baru saja menguji ini sekarang dan jika Anda melakukannya of()akan mengembalikan yang dapat diamati tanpa memancarkannext
Stephen Lautier
kosong sekarang sudah ditinggalkan, gunakan KOSONG sebagai gantinya (digunakan sebagai konstanta alih-alih sebagai metode, lihat jawaban oleh Simon_Weaver).
EriF89
Harap diingat, dari () tidak memancarkan nilai apa pun. Jika Anda menginginkannya, Anda harus memberikan nilai apa pun, bahkan tidak terdefinisi atau nol adalah ok untuk itu: of (null) mengeluarkan nilai (dan proses dengan metode tap / berlangganan), sedangkan dari () tidak.
Maxim Georgievskiy
51

RxJS6 (tanpa paket kompatibilitas yang diinstal)

Sekarang ada EMPTYkonstanta dan emptyfungsi.

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

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

Observable.empty() tidak ada lagi.

Simon_Weaver
sumber
Jika Anda memiliki konflik seperti empty()fungsi yang sudah Anda dapat katakan import { empty as rxEmpty }atau import { empty as _empty }dan kemudian lakukan rxEmpty()atau _empty(). Tentu saja itu hal yang sangat tidak standar untuk dilakukan dan saya tidak benar-benar merekomendasikannya, tapi saya yakin saya bukan satu-satunya yang terkejut. RxJS berpikir layak mengimpor fungsi seperti ofdan emptyke namespace saya!
Simon_Weaver
1
Hati-hati jika menggunakan Angular karena ada juga import { EMPTY } from "@angular/core/src/render3/definition";yang sama sekali bukan yang Anda inginkan. Jadi, jika Anda mendapatkan kesalahan aneh, pastikan Anda tidak mengimpornya secara tidak sengaja.
Simon_Weaver
Observable.empty()sebenarnya masih ada tetapi sudah tidak digunakan lagi EMPTY.
Alexander Abakumov
39

Dalam kasus saya dengan Angular2 dan rxjs, ini bekerja dengan:

import {EmptyObservable} from 'rxjs/observable/EmptyObservable';
...
return new EmptyObservable();
...
Marcel Tinner
sumber
7
termasuk denganimport {EmptyObservable} from 'rxjs/observable/EmptyObservable';
Kildareflare
mendapatkan kesalahan seperti ini, APAKAH saya perlu mengkonfigurasi sesuatu di sistem-config? Penolakan Janji Tidak Tertangani: (SystemJS) Kesalahan XHR (404 Tidak Ditemukan) memuat localhost: 9190 / node_modules / rxjs / Observable / EmptyObservable.js Kesalahan: Kesalahan XHR (404 Tidak Ditemukan) memuat localhost: 9190 / node_modules / rxjs / Dapat Diamati / EmptyObservable. js
user630209
29

Ya, ada operator kosong

Rx.Observable.empty();

Untuk naskah, Anda dapat menggunakan from:

Rx.Observable<Response>.from([])
Toan Nguyen
sumber
Saya mendapatkan Rx.Observable<{}>tidak dapat ditugaskan Observable<Response>, saya mencoba Rx.Observable<Response>.empty()tetapi tidak berhasil
Murhaf Sousli
Saya mengubah jenis kembali ke Observable<any>dan itu berhasil, terima kasih sobat.
Murhaf Sousli
2
Seharusnya Rx.Observable.from([])tanpa <Response>. Kalau tidak mendapatkan kesalahan "ekspresi yang diharapkan".
Andriy Tolstoy
2
Anda juga bisa menggunakan Rx.Observable.of([]).
Andriy Tolstoy
1
@ AndriyTolstoy Saya tidak yakin ini setara. Di Observable.of([]), ada satu nilai yang dipancarkan ( []) dan kemudian aliran selesai. Dengan Observable.from([]), tidak ada nilai yang dipancarkan, streaming selesai dengan segera.
Pac0
24

Beberapa cara untuk membuat Empty Observable:

Mereka hanya berbeda pada bagaimana Anda akan menggunakannya lebih lanjut (peristiwa apa yang akan memancarkan setelah: next, completeatau do nothing) misalnya:

  • Observable.never() - Tidak memancarkan acara dan tidak pernah berakhir.
  • Observable.empty()- Hanya memancarkan complete.
  • Observable.of({})- memancarkan keduanya nextdan complete(Objek kosong literal diteruskan sebagai contoh).

Gunakan sesuai kebutuhan Anda)

Andrii Verbytskyi
sumber
13

Anda dapat mengembalikan Observable.of (empty_variable), misalnya

Observable.of('');

// or
Observable.of({});

// etc
Chybie
sumber
2

Atau Anda dapat mencoba ignoreElements()juga

Tuong Le
sumber
1

RxJS 6

Anda dapat menggunakan juga dari fungsi seperti di bawah ini:

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

setelah impor:

import {from} from 'rxjs';
Tidak
sumber
2
Ini akan membuat Observable yang akan menyediakan satu elemen (string kosong), sehingga tidak terlihat seperti jawaban yang tepat untuk pertanyaan khusus ini.
BrunoJCM
1

Datang ke sini dengan pertanyaan serupa, di atas tidak berfungsi untuk saya "rxjs": "^6.0.0"di:, untuk menghasilkan yang dapat diamati yang tidak memancarkan data yang perlu saya lakukan:

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

Coba ini

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
sumber