我有一个外在的Observable
。内部Obersvable有时会出现错误,可以通过重试来解决。
function sm$(val) {
if (Math.random() > .4) {
return Rx.Observable.throw(val)
} else {
return Rx.Observable.of(val)
}
}
function sm(val) {
return Rx.Observable.of(val)
.switchMap(sm$)
.catch(() => Rx.Observable.of(val).delay(1000).switchMap(sm))
}
Rx.Observable
.interval(500)
.switchMap(sm)
.take(5)
.subscribe(
val => console.log("val:", val),
err => console.log("err:", err),
() => console.log("complete")
)

<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.4.0/Rx.min.js"></script>
&#13;
这个日志,即:
val: 1
val: 2
val: 6
val: 10
val: 11
complete
当我在catch块中返回延迟的observable时,它无法正常工作,只会跳过一些值。没有延迟,它按预期工作,但这不是我想要的。我希望延迟反复推迟。
function sm$(val) {
if (Math.random() > .4) {
return Rx.Observable.throw(val)
} else {
return Rx.Observable.of(val)
}
}
function sm(val) {
return Rx.Observable.of(val)
.switchMap(sm$)
.catch(() => Rx.Observable.of(val).switchMap(sm))
// removed the delay(1000)
}
Rx.Observable
.interval(500)
.switchMap(sm)
.take(5)
.subscribe(
val => console.log("val:", val),
err => console.log("err:", err),
() => console.log("complete")
)
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.4.0/Rx.min.js"></script>
&#13;
这个日志总是这样,这就是我的期望:
val: 0
val: 1
val: 2
val: 3
val: 4
complete
答案 0 :(得分:2)
问题是您正在使用Observable.interval(500).switchMap(sm)
。
特别是您案例中的switchMap
。即使您在内部Observable上使用Observable.interval
时,源delay(1000)
也会继续发光,只是因为switchMap
它在1000ms后想要发出时已经取消订阅。
所以看起来您可以使用concatMap
代替外部switchMap
。
function sm$(val) {
if (Math.random() > .4) {
return Rx.Observable.throw(val)
} else {
return Rx.Observable.of(val)
}
}
function sm(val) {
return Rx.Observable.of(val)
.switchMap(sm$)
.catch(() => Rx.Observable.of(val).delay(1000).switchMap(sm))
}
Rx.Observable
.interval(500)
.concatMap(sm)
.take(5)
.subscribe(
val => console.log("val:", val),
err => console.log("err:", err),
() => console.log("complete")
)
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.4.0/Rx.min.js"></script>
&#13;
答案 1 :(得分:0)
我认为这个问题与你使用延迟1000毫秒同时在发出5个事件后完成流的事实有关,每个事件每500毫秒发生一次。
这意味着由于catch
块而延迟的延迟发射可以在流完成后到达。
如果你减少延迟,你可能会得到你想要的东西。我还添加了一些日志以获得更好的图片
import {Observable} from 'rxjs';
function sm$(val) {
if (Math.random() > .4) {
return Observable.throw(val)
} else {
return Observable.of(val)
}
}
function sm(val) {
return Observable.of(val)
.switchMap(sm$)
.catch(() => {
console.log('error', val);
return Observable.of(val).delay(10).switchMap(d => sm(d));
})
}
Observable
.interval(500)
.switchMap(sm)
.take(5)
.subscribe(
val => console.log("val:", val),
err => console.log("err:", err),
() => console.log("complete")
)