场景:我有一个customerID字符串,用于查询多个不同的后端系统:日历,帮助台,ERP,CRM等。我想编译单个报告。 所以我粗略地(psydocode):
Result myResult = new Result();
Observable<Cal> cal = Calbackend.get(customerid);
cal.subscribe(calentry -> myResult.addCal(calentry));
Observable<Erp> erp = ERPbackend.get(customerid);
erp.subscribe(erpentry -> myResult.addErp(erpentry));
Observable<Help> help = Helpbackend.get(customerid);
help.subscribe(helpentry -> myResult.addHelp(helpentry));
Observable<Crm> crm = CRMbackend.get(customerid);
crm.subscribe(crmentry -> myResult.addCrm(crmentry));
// Magic here?
return result;
我想到的方法:使用defer()
来阻止开始,然后另外为每个订阅count()
。然后我可以对计数元素进行压缩,因为它们每个只发出一个项目(而其他项目将有不同数量的事件)。但是,如果myResult.add
执行速度低于count()
,则可能会导致数据丢失。
我想到的另一个选项是为每个订阅设置一个布尔标志数组,并检查每个完成(和错误)事件(如果所有这些都已完成)并对其执行回调或使用阻塞。 / p>
或者有更好/推荐的方式吗?
答案 0 :(得分:1)
运营商toList
可以与zip
一起使用,如下所示:
Observable<List<Cal>> cal = Calbackend.get(customerid).toList();
Observable<List<Erp>> erp = ERPbackend.get(customerid).toList();
Observable<List<Help>> help = Helpbackend.get(customerid).toList();
Observable<List<Crm>> crm = CRMbackend.get(customerid).toList();
Observable.zip(cal, erp, help, crm,
new Func4<List<Cal>, List<Erp>, List<Help>, List<Crm>, Result>() {
@Override
public Result call(List<Cal> cals, List<Erp> erps, List<Help> helps, List<Crm> crms) {
Result myResult = new Result();
// add all cals, erps, helps and crms to result
return myResult;
}
})
.subscribe(new Subscriber<Result>() {
@Override
public void onNext(Result result) {
// do something with the result
}
...
});
说明:顾名思义,toList
运算符创建源observable发出的项的列表(当源可观察完成时,列表只发出一次)然后使用zip
来组合可观察量的结果。
编辑:如果这些Observable可能会发出错误,您可以使用onErrorReturn
来保持正常流程:
Observable<List<Cal>> cal = Calbackend.get(customerid)
.onErrorReturn(new Func1<Throwable, Cal>() {
@Override
public Cal call(Throwable throwable) {
// Return something in the error case
return null;
}
})
.toList();