for循环中进行联网请求数据、for循环中进行异步数据操作,数据排序错乱问题解决;

for循环中进行联网请求数据,由于网络请求是异步的,第一个网络请求还没有回调,第二次第三次以及后续的网络请求又已经发出去了,有可能后续的网络请求会先回调;这时我们接收到的数据的排序就会错乱;怎么才能让数据和for循环进行异步操作之前的顺序一样呢;

1、网络请求使用同步请求,串型请求,等第一个网络请求回调后再去请求第二个;

2、递归迭代,异步的网络请求,在当前请求完成后再去递归请求下一个;

但是这两种方式都不是并发的,如果数据特别的多一个一个的去请求就会特别的耗时,我们用for循环异步去请求就会同时相应,速度回很快;

3、重点要说的:for循环中进行联网请求数据,解决数据排序错乱问题。

第一:记录下来这个for循环 原集合的索引位置(集合中的对象添加一个indexes的字段),用来后续的排序;

第二:异步请求后数据会错乱,这时我们根据indexes的大小进行排序;

代码如下:仅留下解决数据排序错乱问题的代码;

private void initNewCars(List<CarInfo> datas) {
    for (int ii = 0; ii < datas.size(); ii++) {
             datas.get(ii).indexes = ii; //保存当前车辆的索引位置,等集合遍历完成后进行排序
    }
    AtomicInteger CarSize = new AtomicInteger(); //等所有的集合都联网循环完毕后再去设置数据
    List<CarInfo> Cars = new ArrayList<>();  //遍历后对数据进行操作生成新的集合
    for (int i = 0; i < datas.size(); i++) {
        int finalI = i;
        clwOwnerApi.getAuthVehicleStatus(datas.get(finalI).getVin_code()) //异步网络请求
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<ResultClw<AuthVehicleStatusBean>>() {
                    @Override
                    public void accept(ResultClw<AuthVehicleStatusBean> result) throws Exception {
                        CarSize.getAndIncrement();
                        if ("SUCCEED".equals(result.status) && result.data != null) {
                            if (!"0".equals(result.data.getAuditResult()) && result.data.getVehicleStatus()){
                            }else {
                                CarInfo carInfo = datas.get(finalI);
                                carInfo.isClw = result.data.getVehicleStatus();
                                Cars.add(carInfo); //数据错乱,需要排序!
                            }
                        } else {
                         UIHelper.showToast(result.errorMessage);
                        }
                        if (CarSize.get() >= datas.size()){ //等所有的集合都循环完成了再去设置数据
                            L.cc("列表排序前:"+GsonUtils.toJson(Cars));
                            //根据保存的索引位置进行排序
                            Collections.sort(Cars, new Comparator<CarInfo>() {
                                @Override
                                public int compare(CarInfo o1, CarInfo o2) {
                                    return o1.indexes - o2.indexes;
                                }
                            });
                            L.cc("列表排序后:"+GsonUtils.toJson(Cars));
                        }
                    }
                }, throwable -> {
                    L.e(throwable,throwable.getMessage());
                    CarSize.getAndIncrement();
                    UIHelper.showToast("响应服务器失败,请检查网络连接");
                });
    }
}

对集合的排序参考:https://blog.csdn.net/veryisjava/article/details/51675036

CarInfo对象:

public class CarInfo {

    private String id;
    private String series;
    private String owner_name;
    private String vin_code;
    private String is_default;
    private String uuid;
    private String deliver_date;
    private String vin_name;
    private String card_id;
    private String auth_date;
    private String mobile;
    public boolean isClw;
    public int indexes; //记录当前的位置,用来排序
}

**大致思路:

1、判断集合是否循环完成:异步操作,等所有的异步都完成了再去设置数据;使用AtomicInteger记录数据是否全部遍历完成了;

2、数据错乱问题:先给原数据添加索引位置字段,记录原数据的顺序;异步操作集合后数据错乱,在根据数据的索引字段去排序就OK了,这样的数据的顺序还是和原数据的顺序是一致的,并且是并发的异步请求,速度快效率高;


猜你喜欢

转载自blog.csdn.net/qq_35605213/article/details/80844068