如何使用缓存通过`.publishReplay()`在RxJS Observable上设置超时?

时间:2017-01-23 19:12:33

标签: javascript rxjs rxjs5

我创建了一个Observable,可以在一段时间内缓存他们的结果。这个例子很棒,非常实用!!但我无法为项目生产者设置超时。我试图在mockDataFetch()内使用超时运算符,但在第一个失败的项目之后,流无法恢复。 如何实现超时的mockDataFetch

这正是我所做的:

const Observable = Rx.Observable;

var counter = 1;
var updateRequest = Observable.defer(() => mockDataFetch())
    .publishReplay(1, 1000)
    .refCount();

function mockDataFetch() {
    return Observable.of(counter++)
        .delay(Math.floor((Math.random() * 100) + 1))
        .timeout(50);
}

function mockHttpCache() {
    return updateRequest
        .take(1);
}

另一方面,如果在mockDataFetch内获得一个Excpetion会怎样?我希望在下一个项目上(在1000毫秒后,因为它在publishReplay方法中定义),observable会发出一个新项目。

1 个答案:

答案 0 :(得分:1)

我想我应该更新这个例子并添加这个用例,因为这是一种非常常见的情况(无论如何,我很高兴你发现它很有用!)。

当从mockDataFetch()返回的Observable发送错误/完成通知时,Subject inside标记为已停止(请参阅说明Rx.Subject loses events),因此不会重新提交任何项目。理想情况下,您可以使用catch()内的mockDataFetch()运算符来捕获所有错误:

function mockDataFetch() {
    return Observable.of(counter++)
        .delay(Math.floor((Math.random() * 100) + 1))
        .timeout(50)
        .catch(err => Observable.of('This request is broken.'));
}

查看现场演示:https://jsbin.com/jiguti/5/edit?js,console

此处的输出可能如下所示:

Response 0: This request is broken.
Response 50: This request is broken.
Response 200: This request is broken.
Response 1200: 2
Response 1500: 2
Response 3500: This request is broken.