ฉันจะสร้างสิ่งที่สังเกตได้ด้วยความล่าช้าได้อย่างไร


93

คำถาม

สำหรับวัตถุประสงค์ในการทดสอบผมสร้างObservableวัตถุที่แทนที่สังเกตได้ว่าจะได้รับการส่งกลับโดยการโทร http Httpเกิดขึ้นจริงกับ

สิ่งที่สังเกตได้ของฉันถูกสร้างขึ้นด้วยรหัสต่อไปนี้:

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

สิ่งนี้คือสิ่งที่สังเกตได้นี้จะเปล่งออกมาทันที มีวิธีเพิ่มการหน่วงเวลาแบบกำหนดเองให้กับการปล่อยหรือไม่?


ติดตาม

ฉันลองสิ่งนี้:

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

แต่ดูเหมือนจะไม่ได้ผล



ฉันพยายามเชื่อมโยง.create(...)ด้วย.delay(1000)แต่มันไม่ได้ผล: Observable_1.Observable.create (... ) ความล่าช้าไม่ใช่ฟังก์ชัน
Adrien Brunelat

1
คุณพยายามทำอะไรให้สำเร็จ?
GünterZöchbauer

คุณสมัครรับข้อมูลที่สังเกตได้หรือไม่?
shusson

ปลอมความล่าช้าในการตอบสนอง Http ด้วยการสังเกตของฉันเอง @shusson ใช่คลาสที่ฉันกำลังทดสอบกำลังเรียกใช้บริการ (ฉันพยายามล้อเลียน) สำหรับสิ่งที่สังเกตได้เพื่อที่จะสมัครสมาชิก
Adrien Brunelat

คำตอบ:


145

ใช้การนำเข้าต่อไปนี้:

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

ลองสิ่งนี้:

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

อัพเดท: RXJS 6

โซลูชันข้างต้นใช้งานไม่ได้อีกต่อไปใน RXJS เวอร์ชันใหม่กว่า (และของเชิงมุมเป็นต้น)

ดังนั้นสถานการณ์คือฉันมีอาร์เรย์ของรายการที่จะตรวจสอบกับ API ด้วย API ยอมรับเพียงรายการเดียวและฉันไม่ต้องการฆ่า API ด้วยการส่งคำขอทั้งหมดในครั้งเดียว ดังนั้นฉันต้องปล่อยรายการตามกำหนดเวลาบนสตรีม Observable โดยมีการหน่วงเวลาเล็กน้อย

ใช้การนำเข้าต่อไปนี้:

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

จากนั้นใช้รหัสต่อไปนี้:

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

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

โดยพื้นฐานแล้วจะสร้าง 'ล่าช้า' สังเกตได้ใหม่สำหรับทุกรายการในอาร์เรย์ของคุณ อาจมีวิธีอื่น ๆ อีกมากมายในการทำเช่นนี้ แต่วิธีนี้ใช้ได้ดีสำหรับฉันและสอดคล้องกับรูปแบบ RXJS 'ใหม่'


2
ไม่มีคุณสมบัติ 'of' ในประเภท 'typeof Observable' คุณนำเข้า Observable ของคุณด้วยimport {Observable} from 'rxjs/Observable';หรือไม่?
Adrien Brunelat

1
จากหน้านี้: npmjs.com/package/rxjs ฉันอนุมานได้ว่าฉันต้องนำเข้าด้วยimport 'rxjs/add/observable/of';. คุณบังเอิญทำสิ่งเดียวกันหรือไม่? มันยังแปลกอยู่เพราะมันจะไม่เชื่อมโยงกับ. delay (... ) และมันแสดงข้อผิดพลาดเมื่อฉันลองrxjs/add/observable/delay...
Adrien Brunelat

4
ควร of(item.pipe ( delay( 1000 ) ))ได้รับการof(item))).pipe(delay(1000)พยายามที่จะท่ออาร์เรย์ให้ฉันข้อผิดพลาด
ดอนโทมัส Boyle

1
นี่คือสิ่งที่ใช้ได้ผลสำหรับฉันกับ rxjs6: from ([1, 2, 3, 4, 5, 6, 7]) ไปป์ (concatMap (num => of (num) .pipe (delay (1000)))) สมัครสมาชิก (x => console.log (x));
เบิร์ต

1
โซลูชันของ @MikeOne ก็ใช้ได้ผลเช่นกัน น่าเศร้าที่รหัสจำนวนมากจำเป็นสำหรับเรื่องง่ายๆเช่นนี้ ...
Codev

103

ใน RxJS 5+ คุณสามารถทำได้เช่นนี้

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

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

ใน RxJS 6+

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

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

หากคุณต้องการหน่วงเวลาแต่ละค่าที่ปล่อยออกมาให้ลอง

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

4
วิธีแก้ปัญหาที่สะอาดที่สุดในความคิดของฉัน
Maayao

"โซลูชัน" นี้ใช้ได้เฉพาะเมื่อคุณปล่อยออกมาหนึ่งรายการ ไม่มีการเรียกตัวดำเนินการหน่วงเวลาสำหรับแต่ละองค์ประกอบในสิ่งที่สังเกตได้ นั่นคือเหตุผลที่ต้องใช้โซลูชัน concatMap ที่น่ากลัว
Rick O'Shea

1
@ RickO'Shea คำถามคือค่าที่ปล่อยออกมาประมาณหนึ่งนั่นคือเหตุผลว่าทำไมวิธีนี้
Adrian Ber

1
สดและสะอาดมาก!
Nahn

ฉันอัปเดตคำตอบสำหรับความล่าช้าหลายครั้ง @ RickO'Shea
Adrian Ber

12

สิ่งที่คุณต้องการคือตัวจับเวลา:

// 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
คำตอบที่ดีอย่าลืมยกเลิกการรับข่าวสาร
Sami

8

มันสายไปหน่อยที่จะตอบ ... แต่ในกรณีที่อาจมีคนกลับมาที่คำถามนี้เพื่อหาคำตอบ

'delay' เป็นคุณสมบัติ (ฟังก์ชัน) ของ Observable

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

สิ่งนี้ได้ผลสำหรับฉัน ...


1
import 'rxjs/add/operator/delay' ให้ข้อผิดพลาดนี้ทันที: ไม่พบโมดูล: ข้อผิดพลาด: ไม่สามารถแก้ไข 'rxjs / add / operator / delay'
Aggie Jon จาก

ทำไมคุณถึงเรียกคุณว่าของปลอมที่สังเกตได้ในเมื่อมันค่อนข้างจริง? :)
lagoman

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.