Làm thế nào tôi có thể tạo ra một sự chậm trễ có thể quan sát được


93

Câu hỏi

Với mục đích thử nghiệm, tôi đang tạo Observablecác đối tượng thay thế các đối tượng có thể quan sát được sẽ được trả về bởi một lệnh gọi http thực tế Http.

Có thể quan sát của tôi được tạo bằng mã sau:

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

Vấn đề là, điều này có thể quan sát được phát ra ngay lập tức. Có cách nào để thêm độ trễ tùy chỉnh vào phát xạ của nó không?


Theo dõi

Tôi đã thử điều này:

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

Nhưng nó dường như không hoạt động.



Tôi đã cố gắng liên kết .create(...)với .delay(1000)nhưng nó không hoạt động: Observable_1.Observable.create (...). Delay không phải là một hàm.
Adrien Brunelat

1
Chính xác thì bạn đang cố đạt được điều gì?
Günter Zöchbauer

bạn đang đăng ký để quan sát?
shusson

Giả mạo độ trễ phản hồi Http với sự quan sát của riêng tôi. @shusson vâng, lớp mà tôi đang kiểm tra đang gọi dịch vụ (tôi đang cố gắng mô phỏng) cho những người có thể quan sát để đăng ký.
Adrien Brunelat

Câu trả lời:


145

Sử dụng các phép nhập sau:

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

Thử đi:

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

CẬP NHẬT: RXJS 6

Giải pháp trên không thực sự hoạt động nữa trong các phiên bản RXJS mới hơn (và của góc cạnh chẳng hạn).

Vì vậy, tình huống là tôi có một loạt các mục để kiểm tra với một API. API chỉ chấp nhận một mục duy nhất và tôi không muốn hủy API bằng cách gửi tất cả các yêu cầu cùng một lúc. Vì vậy, tôi cần bản phát hành theo thời gian của các mục trên luồng Có thể quan sát với độ trễ nhỏ ở giữa.

Sử dụng các phép nhập sau:

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

Sau đó, sử dụng mã sau:

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

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

Về cơ bản, nó tạo ra một Observable mới 'bị trì hoãn' cho mọi mục trong mảng của bạn. Có thể có nhiều cách khác để làm điều đó, nhưng cách này hiệu quả với tôi và tuân thủ định dạng RXJS 'mới'.


2
Thuộc tính 'of' không tồn tại trên loại 'typeof Observable'. Bạn có nhập có thể quan sát của bạn với import {Observable} from 'rxjs/Observable';?
Adrien Brunelat 23/02/17

1
Từ trang này: npmjs.com/package/rxjs . Tôi suy luận rằng tôi phải nhập rõ ràng với import 'rxjs/add/observable/of';. Bạn có tình cờ làm điều tương tự không? Nó vẫn còn lẻ mặc dù, vì nó sẽ không chuỗi với .delay (...) và nó hiển thị lỗi khi tôi cố gắng rxjs/add/observable/delay...
Adrien Brunelat

4
nên of(item.pipe ( delay( 1000 ) ))được of(item))).pipe(delay(1000)cố gắng để ống mảng đã cho tôi lỗi
Don Thomas Boyle

1
Đây là những gì làm việc cho tôi với rxjs6: from ([1, 2, 3, 4, 5, 6, 7]). Pipe (concatMap (num => of (num) .pipe (delay (1000)))). subscribe (x => console.log (x));
robert

1
Giải pháp của @MikeOne cũng phù hợp với tôi. Đáng buồn là quá nhiều mã là cần thiết cho một vấn đề đơn giản như vậy ...
Codev

103

Trong RxJS 5+, bạn có thể làm như thế này

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

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

Trong RxJS 6+

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

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

Nếu bạn muốn trì hoãn mỗi giá trị được phát ra, hãy thử

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

4
Giải pháp sạch nhất theo ý kiến ​​của tôi.
Maayao

"Giải pháp" này chỉ hoạt động nếu bạn phát ra một mục. Toán tử trễ không được gọi cho mỗi phần tử trong một quan sát được. Đó là lý do tại sao giải pháp concatMap khủng khiếp được yêu cầu.
Rick O'Shea

1
@ RickO'Shea, câu hỏi là về một giá trị được phát ra, vì vậy đó là lý do tại sao giải pháp này.
Adrian Ber

1
Thật tươi và thật sạch !
Nahn

Tôi đã cập nhật câu trả lời của mình cho nhiều lần chậm trễ @ RickO'Shea
Adrian Ber

13

Những gì bạn muốn là một bộ đếm thời gian:

// 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
Câu trả lời tốt, đừng quên để bỏ đăng ký
Sami

8

Còn hơi muộn để trả lời ... nhưng đề phòng ai đó quay lại câu hỏi này để tìm kiếm câu trả lời

'delay' là thuộc tính (chức năng) của một

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

Điều này đã làm việc cho tôi ...


1
import 'rxjs/add/operator/delay' đưa ra lỗi này ngay bây giờ: Không tìm thấy mô-đun: Lỗi: Không thể giải quyết 'rxjs / add / operator / delay'
Aggie Jon của 87

Tại sao bạn lại gọi bạn là giả có thể quan sát được trong khi nó khá thật? :)
lagoman

0

import * as Rx from 'rxjs/Rx';

Chúng ta nên thêm nhập ở trên để mã đòn hoạt động

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

obs.subscribe(value => console.log('Subscriber: ' + value));
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.