本文介紹了如何捕獲失敗的呼叫并繼續其余的網絡呼叫?的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!
問題描述
我正在進行5個并行網絡調用,模擬其中4個成功,1個失敗。
失敗的調用會導致整個Single.zip()
失敗,并且我無法獲取其他4個網絡調用的結果,即使它們已經成功。
如何處理Single.zip()
中單個網絡調用失敗的錯誤,并獲取成功的網絡調用的結果?
private Single<BigInteger> createNetworkCall(){
return Single.fromCallable(() -> {
return service.getBalance("validaddress").execute();
}).subscribeOn(Schedulers.io());
}
private Single<BigInteger> createFailedNetworkCall(){
return Single.fromCallable(() -> {
return service.getBalance("invalidaddress").execute();
}).subscribeOn(Schedulers.io());
}
private void makeParallelCalls(){
List<Single<BigInteger>> iterable = new ArrayList<>();
iterable.add(createNetworkCall());
iterable.add(createNetworkCall());
iterable.add(createNetworkCall());
iterable.add(createNetworkCall());
iterable.add(createFailedNetworkCall());
Single.zip(iterable, (results) -> {
Log.d(TAG, "makeParallelCalls: " + Arrays.toString(results));
return results;
}).observeOn(AndroidSchedulers.mainThread())
.subscribe(results-> {
Log.d(TAG, "onSuccess: makeParallelCalls: " + results);
}, (exception) -> {
Log.e(TAG, "onError: makeParallelCalls", exception);
});
}
推薦答案
捕獲異常,不允許該錯誤中斷Single.Zip。
例如,在您的請求工廠中,返回可選而不是響應。
private Single<Optional<Long>> performNetworkCall(int n){
return Single.fromCallable(() -> {
if (n % 2 == 0) {
throw new Exception("failed call");
}
return 0L;
}).subscribeOn(Schedulers.io())
.map(Optional::of)
.onErrorReturnItem(Optional.empty());
// or .onErrorReturn(exception -> Optional.empty());
}
private void makeParallelCalls(){
List<Single<BigInteger>> iterable = new ArrayList<>();
iterable.add(performNetworkCall(1));
iterable.add(performNetworkCall(2));
iterable.add(performNetworkCall(3));
iterable.add(performNetworkCall(4));
iterable.add(performNetworkCall(5));
Single.zip(iterable, (results) -> {
for (Object result : results) {
var optional = (Optional<Integer>)result;
if (optional.isEmpty()) {
// this one failed, no data
} else {
var response = optional.get();
}
}
return results;
});
}
您可以將可選替換為包含附加信息的自定義類,例如導致失敗的異常或錯誤信息。
如果您有恢復選項,則可以改用.onErrorResumeNext
。
這篇關于如何捕獲失敗的呼叫并繼續其余的網絡呼叫?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,