Ответ 1
Чистый и аккуратный подход подождать, пока все ваши запросы будут выполнены, - это использовать Retrofit2 вместе с RxJava2 и его zip
функцией.
То, что делает zip
, в основном создает новые наблюдаемые, которые ждут, пока все ваши модифицированные запросы Observable
не будут выполнены, а затем он испустит свой собственный результат.
Вот пример интерфейса Retrofit2 с Observables:
public interface MyBackendAPI {
@GET("users/{user}")
Observable<User> getUser(@Path("user") String user);
@GET("users/{user}/photos")
Observable<List<Photo>> listPhotos(@Path("user") String user);
@GET("users/{user}/friends")
Observable<List<User>> listFriends(@Path("user") String user);
}
В коде, где вы собираетесь делать несколько запросов, и только после того, как все они завершат что-то еще, вы можете написать следующее:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.example.com/")
.build();
MyBackendAPI backendApi = retrofit.create(MyBackendAPI.class);
List<Observable<?>> requests = new ArrayList<>();
// Make a collection of all requests you need to call at once, there can be any number of requests, not only 3. You can have 2 or 5, or 100.
requests.add(backendApi.getUser("someUserId"));
requests.add(backendApi.listPhotos("someUserId"));
requests.add(backendApi.listFriends("someUserId"));
// Zip all requests with the Function, which will receive the results.
Observable.zip(
requests,
new Function<Object[], Object>() {
@Override
public Object apply(Object[] objects) throws Exception {
// Objects[] is an array of combined results of completed requests
// do something with those results and emit new event
return new Object();
}
})
// After all requests had been performed the next observer will receive the Object, returned from Function
.subscribe(
// Will be triggered if all requests will end successfully (4xx and 5xx also are successful requests too)
new Consumer<Object>() {
@Override
public void accept(Object o) throws Exception {
//Do something on successful completion of all requests
}
},
// Will be triggered if any error during requests will happen
new Consumer<Throwable>() {
@Override
public void accept(Throwable e) throws Exception {
//Do something on error completion of requests
}
}
);
Все это :)
На всякий случай хочу показать, как выглядит тот же код в Kotlin
.
val retrofit = Retrofit.Builder()
.baseUrl("https://api.example.com/")
.build()
val backendApi = retrofit.create(MyBackendAPI::class.java)
val requests = ArrayList<Observable<*>>()
requests.add(backendApi.getUser())
requests.add(backendApi.listPhotos())
requests.add(backendApi.listFriends())
Observable
.zip(requests) {
// do something with those results and emit new event
Any() // <-- Here we emit just new empty Object(), but you can emit anything
}
// Will be triggered if all requests will end successfully (4xx and 5xx also are successful requests too)
.subscribe({
//Do something on successful completion of all requests
}) {
//Do something on error completion of requests
}