我希望在rxjs中执行此操作:
非工作伪代码:
class InfoMessage {
constructor(public message: string) {}
}
doAllRequests() : Observable<InfoMessage> {
return Observable.create((obs: Observer<InfoMessage>) => {
doRequest("http://test1.com").map((res: RxRequestResponse) => obs.next(new InfoMessage("request1 done")));
doRequest("http://test2.com").map((res: RxRequestResponse) => obs.next(new InfoMessage("request2")));
doRequest("http://test3.com").map((res: RxRequestResponse) => obs.next(new InfoMessage("request3")));
obs.complete();
});
}
doRequest(url: string) : Observable<RxRequestResponse> {
// use some http client which is wrapped in an Observable of type RxRequestResponse
}
doAllRequests().subscribe(next => console("Message: " + next.message));
更新马丁的建议答案: 你的答案似乎有效,但只有当我订阅第一个请求时才这样:
Observable.create((observer: Observer<InfoMessage>) => {
doRequest("http://test1.com")
.do(response => observer.next(new InfoMessage("request1 done")))
.concatMap(() => doRequest("http://test2.com"))
.do(response => observer.next(new InfoMessage("request2")))
.concatMap(() => doRequest("http://test3.com"))
.do(response => {
observer.next(new InfoMessage("request3"));
observer.complete();
}).subscribe();
})
我真的想推迟订阅并将其留给doAllRequests()的调用者。有什么想法吗?
更新:Quentin建议的回答
该解决方案可以正常工作,并且对于我将要运行的大型脚本(具有大量请求),在代码冗长(或者更缺乏代码)方面可以更好地扩展。
由于这是我现在最终使用的那个,我正在改变我接受的答案。但马丁,我对此感到内疚。我还有一个赞成你...我们好吗?
答案 0 :(得分:1)
如果每个HTTP呼叫独立于前一个呼叫的结果,您可以使用concatMap
链接它们:
Observable.create((observer: Observer<InfoMessage>) => {
doRequest("http://test1.com")
.do(response => observer.next(new InfoMessage("request1 done")))
.concatMap(() => doRequest("http://test2.com"))
.do(response => observer.next(new InfoMessage("request2")))
.concatMap(() => doRequest("http://test3.com"))
.do(response => {
observer.next(new InfoMessage("request3"));
observer.complete();
});
})
不要忘记你需要从你的函数中返回Observable.create
并订阅它。
答案 1 :(得分:1)
由于您的doRequest()
已经返回了一个可观察对象,为什么不尝试将所有请求组合在一起并将响应转换为单个流?您可以使用forkJoin:
doAllRequests() : Observable<InfoMessage> {
return forkJoin(
doRequest("http://test1.com"),
doRequest("http://test2.com"),
doRequest("http://test3.com")
).pipe(
mergeMap((responsesArray: any[]) => from(responsesArray)),
map((response: any) => new InfoMessage(response))
);
}
this.doAllRequests().subscribe();