angularService.method1
称为id,我需要下一个请求我想每秒致电angularService.method2(id)
,直到收到回复{success: true}
或:
{success: false, errors: [{errorCode: 'code', errorMessage: 'some error message'}]
经过几个小时的尝试,我来到了这个版本,实际上它可行。但我有一些问题
这是一个正确的实现还是我在这里遇到了一些问题?
this.angularService
.method1(data)
.flatMap((res) => {
return Observable
.interval(1000)
.flatMap(() => this.angularService.method2(res.id))
.concatMap(resp => {
return (resp.success) ? Observable.of(resp, null) : Observable.of(resp);
})
.takeWhile(resp => resp);
})
.switchMap((res) => {
return (!res.success && res.errors) ? Observable.throw(res.errors) : Observable.of(res);
})
.subscribe(
(next) => console.log(next),
(err) => console.log(err),
() => console.log('finished')
);
答案 0 :(得分:0)
我知道你要调用method2
,直到得到第一个非null或未定义的响应,然后关闭流。
如果这是正确的,那么我会开始编写一个接收id
参数的函数,然后每秒调用method2
直到得到答案,如
callMethod2EverySecond(id) {
return Observable.interval(1000)
.mergeMap(() => this.angularService.method2(id))
.filter(resp => resp !== null)
.take(1)
}
此功能执行以下操作
mergeMap
是新的
名称flatMap
operator
take
运营商执行)然后你可以在外部逻辑中使用该函数,例如
this.angularService
.method1(data)
.switchMap(res => callMethod2EverySecond(res.id))
.subscribe(
res => {
if (!res.success && res.errors) {console.error(res)}
else {console.log(res)}
},
(err) => console.log(err),
() => console.log('finished')
);
考虑以下几点:
subscribe
的参数,您不需要抛出Observables
作为错误使用angularService.method1和angularService.method2 模拟的工作代码示例
以下是根据上述假设的代码的工作示例。
method1
和method2
已经模拟了angularService。
import {Observable} from 'rxjs';
method1('123')
.switchMap(res => callMethod2EverySecond(res.id))
.subscribe(
res => {
if (!res.success && res.errors) {console.error(res)}
else {console.log('subscription processing', res)}
},
(err) => console.log(err),
() => console.log('finished')
);
function callMethod2EverySecond(id) {
return Observable.interval(10)
.mergeMap(data => method2(id, data))
.do(resp => console.log('resp', resp))
.filter(resp => resp !== null)
.take(1)
}
function method1(data: string) {
return Observable.of({id: data});
}
function method2(id: string, interval: number) {
const ret = randomIntInc(0,1) === 0 ? null : {success: true, errors: null, interval, id};
return Observable
.of(ret)
.delay(randomIntInc(0,2000));
}
function randomIntInc(low, high) {
return Math.floor(Math.random() * (high - low + 1) + low);
}