java - 如何在继续循环之前等待回调完成?
问题描述
我正在尝试在 for 循环中添加restMedia
到restaurantMediaList
in中。onResponse
但是,当循环结束时,restaurantMediaList
为空。onResponse
我怎样才能解决这个问题,让它在进行下一次迭代之前先等待完成?
public void getImages(List<Restaurant> restaurantList, OnImageReceivedCallback callback){
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://example.com")
.addConverterFactory(GsonConverterFactory.create())
.build();
WordpressAPICall wordpressAPICall = retrofit.create(WordpressAPICall.class);
for(int i = 0; i < restaurantList.size(); i++){
String featuredMediaURL = restaurantList.get(i).get_links().getFeaturedMedia().get(0).getHref();
featuredMediaURL.substring(featuredMediaURL.indexOf("v2")+1);
Call<RestaurantMedia> restMediaCall = wordpressAPICall.getImage(featuredMediaURL);
restMediaCall.enqueue(new Callback<RestaurantMedia>() {
@Override
public void onResponse(Call<RestaurantMedia> call, Response<RestaurantMedia> response) {
RestaurantMedia restMedia = response.body();
restaurantMediaList.add(restMedia);
//callback.onRestaurantListReceived(restaurantModels, restMedia);
}
@Override
public void onFailure(Call<RestaurantMedia> call, Throwable t) {
Log.d("Fail to get media", t.toString());
}
});
}
callback.onImageReceived(restaurantMediaList);
}
解决方案
请记住,有restaurantList.size()
不同的线程(每个都会触发一个网络请求),您唯一的选择是使用一些锁。
如果有一个 API 可以同时获取所有图像,请使用它并使用我的第一个代码来等待结果。
我还建议使用超时,因为如果由于某种原因onResponse
ANDonFailure
不会被调用,您的调用线程将永远休眠。根据需要调整超时。
等待每个线程分别完成非常耗时,所以我建议让它们异步并在所有线程完成后继续。
我将向您展示这两种选择。
等待每一个单独等待:
CountDownLatch countDownLatch = new CountDownLatch(1);
restMediaCall.enqueue(new Callback<RestaurantMedia>() {
@Override
public void onResponse(Call<RestaurantMedia> call, Response<RestaurantMedia> response) {
// Do your thing
countDownLatch.countDown();
}
@Override
public void onFailure(Call<RestaurantMedia> call, Throwable t) {
// Do your thing
countDownLatch.countDown();
}
});
countDownLatch.await(1L, TimeUnit.SECONDS); // join thread with timeout of second
一起等待所有线程:
public void getImages(List<Restaurant> restaurantList, OnImageReceivedCallback callback){
// Do your thing
CountDownLatch countDownLatch = new CountDownLatch(restaurantList.size());
for(int i = 0; i < restaurantList.size(); i++){
// Do your thing
restMediaCall.enqueue(new Callback<RestaurantMedia>() {
@Override
public void onResponse(Call<RestaurantMedia> call, Response<RestaurantMedia> response) {
// Do your thing
countDownLatch.countDown();
}
@Override
public void onFailure(Call<RestaurantMedia> call, Throwable t) {
// Do your thing
countDownLatch.countDown();
}
});
}
countDownLatch.await(1L * restaurantList.size(), TimeUnit.SECONDS); // join thread with timeout of second for each item
}
推荐阅读
- python - numpy 两个数组满足不同的条件
- seal - SEAL 中的解码和解密错误指示符
- r - R:如何在 sapply 之后将列表更改为数据框的向量?
- python - 在 Python 中生成给定游戏列表的可能组合
- file - 在 Talend 中映射之前从文件中提取电子邮件地址
- c# - 在启动 .Net Core 2.0 上使用 Owin 时遇到 NullReferenceException - 设置?
- c - 从另一个数组设置数组大小时遇到问题
- java - 如何在 Spring Reactive Websocket API 中广播消息?
- django - 从网站应对好。(django)
- java - 如何在注释处理器中获取注释参数