Bagaimana saya bisa membuat observable dengan penundaan


92

Pertanyaan

Untuk tujuan pengujian, saya membuat Observableobjek yang menggantikan observable yang akan dikembalikan oleh panggilan http yang sebenarnya dengan Http.

Observable saya dibuat dengan kode berikut:

fakeObservable = Observable.create(obs => {
  obs.next([1, 2, 3]);
  obs.complete();
});

Masalahnya, yang dapat diamati ini memancarkan dengan segera. Apakah ada cara untuk menambahkan penundaan khusus pada emisinya?


Jalur

Saya mencoba ini:

fakeObservable = Observable.create(obs => {
  setTimeout(() => {
    obs.next([1, 2, 3]);
    obs.complete();
  }, 100);
});

Tapi sepertinya tidak berhasil.



Saya mencoba untuk menghubungkan .create(...)dengan .delay(1000)tetapi tidak berhasil: Observable_1.Observable.create (...). Delay bukanlah sebuah fungsi.
Adrien Brunelat

1
Apa sebenarnya yang ingin Anda capai?
Günter Zöchbauer

apakah Anda berlangganan observable?
shusson

Palsu penundaan respons Http dengan pengamatan saya sendiri. @shusson ya, kelas yang saya uji memanggil layanan (saya mencoba mengejek) untuk yang dapat diamati untuk berlangganan.
Adrien Brunelat

Jawaban:


144

Menggunakan impor berikut:

import {Observable} from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/delay';

Coba ini:

let fakeResponse = [1,2,3];
let delayedObservable = Observable.of(fakeResponse).delay(5000);
delayedObservable.subscribe(data => console.log(data));

PEMBARUAN: RXJS 6

Solusi di atas tidak benar-benar berfungsi lagi di versi RXJS yang lebih baru (dan sudut misalnya).

Jadi skenarionya adalah bahwa saya memiliki serangkaian item untuk diperiksa dengan API. API hanya menerima satu item, dan saya tidak ingin menghentikan API dengan mengirim semua permintaan sekaligus. Jadi saya perlu rilis item yang diatur waktunya di aliran Observable dengan sedikit penundaan di antaranya.

Gunakan impor berikut:

import { from, of } from 'rxjs';
import { delay } from 'rxjs/internal/operators';
import { concatMap } from 'rxjs/internal/operators';

Kemudian gunakan kode berikut:

const myArray = [1,2,3,4];

from(myArray).pipe(
        concatMap( item => of(item).pipe ( delay( 1000 ) ))
    ).subscribe ( timedItem => {
        console.log(timedItem)
    });

Ini pada dasarnya menciptakan Observable 'tertunda' baru untuk setiap item dalam array Anda. Mungkin ada banyak cara lain untuk melakukannya, tetapi ini berfungsi dengan baik untuk saya, dan sesuai dengan format RXJS 'baru'.


2
Properti 'dari' tidak ada pada tipe 'typeof Observable'. Apakah Anda mengimpor Observable with Anda import {Observable} from 'rxjs/Observable';?
Adrien Brunelat

1
Dari halaman ini: npmjs.com/package/rxjs . Saya menyimpulkan bahwa saya harus mengimpor secara eksplisit import 'rxjs/add/observable/of';. Apakah Anda kebetulan melakukan hal yang sama? Ini masih aneh, karena tidak akan dirantai dengan .delay (...) dan itu menunjukkan kesalahan ketika saya mencoba rxjs/add/observable/delay...
Adrien Brunelat

4
harus of(item.pipe ( delay( 1000 ) ))harus of(item))).pipe(delay(1000)mencoba untuk pipa array memberi saya kesalahan
Don Thomas Boyle

1
Inilah yang berhasil untuk saya dengan rxjs6: from ([1, 2, 3, 4, 5, 6, 7]). Pipe (concatMap (num => of (num) .pipe (delay (1000)))). berlangganan (x => console.log (x));
robert

1
Solusi @MikeOne juga berhasil untuk saya. Sedih karena begitu banyak kode diperlukan untuk masalah sederhana seperti itu ...
Codev

103

Di RxJS 5+ Anda dapat melakukannya seperti ini

import { Observable } from "rxjs/Observable";
import { of } from "rxjs/observable/of";
import { delay } from "rxjs/operators";

fakeObservable = of('dummy').pipe(delay(5000));

Di RxJS 6+

import { of } from "rxjs";
import { delay } from "rxjs/operators";

fakeObservable = of('dummy').pipe(delay(5000));

Jika Anda ingin menunda setiap nilai yang dipancarkan coba

from([1, 2, 3]).pipe(concatMap(item => of(item).pipe(delay(1000))));

4
Solusi terbersih menurut saya.
Maayao

"Solusi" ini hanya berfungsi jika Anda mengeluarkan satu item. Operator penundaan tidak dipanggil untuk setiap elemen dalam sebuah observable. Itulah mengapa solusi concatMap yang mengerikan diperlukan.
Rick O'Shea

1
@ RickO'Shea, pertanyaannya adalah tentang satu nilai yang dipancarkan, jadi itulah mengapa solusi ini.
Adrian Ber

1
Sangat segar dan sangat bersih!
Nahn

Saya memperbarui jawaban saya untuk beberapa penundaan @ RickO'Shea
Adrian Ber

12

Yang Anda inginkan adalah pengatur waktu:

// RxJS v6+
import { timer } from 'rxjs';

//emit [1, 2, 3] after 1 second.
const source = timer(1000).map(([1, 2, 3]);
//output: [1, 2, 3]
const subscribe = source.subscribe(val => console.log(val));

3
Jawaban bagus, jangan lupa berhenti berlangganan
Sami

8

Agak terlambat untuk menjawab ... tetapi untuk berjaga-jaga mungkin seseorang kembali ke pertanyaan ini mencari jawaban

'delay' adalah properti (fungsi) dari sebuah Observable

fakeObservable = Observable.create(obs => {
  obs.next([1, 2, 3]);
  obs.complete();
}).delay(3000);

Ini berhasil untuk saya ...


1
import 'rxjs/add/operator/delay' memberikan kesalahan ini sekarang: Modul tidak ditemukan: Kesalahan: Tidak dapat menyelesaikan 'rxjs / add / operator / delay'
Aggie Jon dari 87

Mengapa Anda menyebut Anda palsu yang bisa diamati padahal itu cukup nyata? :)
lagoman

0

import * as Rx from 'rxjs/Rx';

Kita harus menambahkan impor di atas untuk membuat kode pukulan berfungsi

Let obs = Rx.Observable
    .interval(1000).take(3);

obs.subscribe(value => console.log('Subscriber: ' + value));
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.