Gecikmeli bir gözlemlenebilirliği nasıl yaratabilirim


92

Soru

Test amacıyla, Observablegerçek bir http çağrısı ile döndürülecek olan gözlemlenebilir olanı değiştiren nesneler oluşturuyorum Http.

Gözlemlenebilirim aşağıdaki kodla oluşturulur:

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

Mesele şu ki, bu gözlemlenebilir anında yayılıyor. Emisyonuna özel bir gecikme eklemenin bir yolu var mı?


Izlemek

Bunu denedim:

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

Ama işe yaramıyor gibi görünüyor.



Ben zincire çalıştı .create(...)ile .delay(1000)ama bir işe vermedi. Observable_1.Observable.create (...) gecikme bir işlev değil.
Adrien Brunelat

1
Tam olarak neyi başarmak istiyorsun?
Günter Zöchbauer

gözlemlenebilir olana abone misin?
shusson

Http yanıt gecikmesini kendi gözlemlenebilirimle taklit edin. @shusson evet, test ettiğim sınıf, gözlemlenebilir olana abone olmak için servisi arıyor (alay etmeye çalışıyorum).
Adrien Brunelat

Yanıtlar:


144

Aşağıdaki içe aktarımların kullanılması:

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

Bunu dene:

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

GÜNCELLEME: RXJS 6

Yukarıdaki çözüm artık RXJS'nin daha yeni sürümlerinde (ve örneğin açısal) gerçekten çalışmıyor.

Öyleyse senaryo, bir API ile kontrol etmem gereken bir dizi öğeye sahip olduğum. API yalnızca tek bir öğeyi kabul ediyor ve tüm istekleri tek seferde göndererek API'yi öldürmek istemiyorum. Bu yüzden, Gözlemlenebilir akıştaki öğelerin arada küçük bir gecikmeyle zamanlanmış olarak yayınlanmasına ihtiyacım var.

Aşağıdaki içe aktarmaları kullanın:

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

Ardından aşağıdaki kodu kullanın:

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

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

Temel olarak dizinizdeki her öğe için yeni bir 'gecikmeli' Gözlemlenebilir oluşturur. Muhtemelen bunu yapmanın birçok yolu vardır, ancak bu benim için iyi çalıştı ve 'yeni' RXJS formatıyla uyumlu.


2
'Of' özelliği, 'typeof Observable' türünde mevcut değil. Observable'ınızı ile import {Observable} from 'rxjs/Observable';mi ithal ediyorsunuz ?
Adrien Brunelat

1
Bu sayfadan: npmjs.com/package/rxjs . Açıkça ithalat yapmak zorunda olduğum sonucuna vardım import 'rxjs/add/observable/of';. Aynı şeyi mi yapıyorsun? Yine de tuhaf, çünkü .delay (...) ile zincirlenmeyecek ve denediğimde bir hata gösteriyor rxjs/add/observable/delay...
Adrien Brunelat

4
gerektiğini of(item.pipe ( delay( 1000 ) ))edilecek of(item))).pipe(delay(1000)boru çalışırken dizi bana hataları verdi
Don Thomas Boyle

1
Rxjs6 ile benim için işe yarayan şey buydu: from ([1, 2, 3, 4, 5, 6, 7]). Pipe (concatMap (num => of (num) .pipe (delay (1000)))). abone (x => console.log (x));
robert

1
@MikeOne'ın çözümü benim için de çalıştı. Ne yazık ki bu kadar basit bir mesele için bu kadar çok kod gerekli ...
Codev

103

RxJS 5+ ile bunu şu şekilde yapabilirsiniz

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

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

RxJS 6+ içinde

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

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

Yayılan her değeri geciktirmek istiyorsanız deneyin

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

4
Bence en temiz çözüm.
Maayao

Bu "çözüm" yalnızca bir öğe yayarsanız işe yarar. Gecikme operatörü, bir gözlemlenebilirdeki her öğe için çağrılmaz. Bu nedenle korkunç concatMap çözümü gereklidir.
Rick O'Shea

1
@ RickO'Shea, soru yayılan bir değerle ilgili, bu yüzden bu çözüm.
Adrian Ber

1
Çok taze ve çok temiz!
Nahn

Birden fazla gecikme için cevabımı güncelledim @ RickO'Shea
Adrian Ber,

12

İstediğin şey bir zamanlayıcı:

// 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
Güzel cevap, abonelikten
Sami

8

Cevap vermek için biraz geç ... ama her ihtimale karşı birisi bu soruya cevap aramak için geri dönebilir

'gecikme' bir Gözlemlenebilir'in özelliğidir (işlevidir)

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

Bu benim için çalıştı ...


1
import 'rxjs/add/operator/delay' şu hatayı veriyor: Modül bulunamadı: Hata: 'rxjs / add / operator / delay' çözümlenemiyor
Aggie Jon, 87

Oldukça gerçekken neden size gözlemlenebilir sahte diyorsunuz? :)
lagoman

0

import * as Rx from 'rxjs/Rx';

Darbe kodunun çalışması için yukarıdaki içe aktarmayı eklemeliyiz

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

obs.subscribe(value => console.log('Subscriber: ' + value));
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.