繁体   English   中英

等待多次回调发生,然后继续

[英]Waiting for multiple Callbacks to occur before proceeding

我正在使用其中包含回调的循环将数据添加到地图。 然后,我将此地图传递到“回收者视图”,但是当我这样做时-该地图是空的,因此没有显示任何内容。 我认为是因为我需要等待回调发生?

下面的循环在我的片段内从OnActivityCreated调用的类中。 这是我的回调发生的方式:

    for (final Map.Entry<String, UserDetails> entry : listOfUsers.entrySet()) {
        getSeasonsData("Seasons", entry.getKey(), new CallBack3() {

            @Override
            public void onSuccess(List<UserSeasons> seasons) {
                userSeasons.put(entry.getKey(), seasons);
            }

            @Override
            public void onError(String error) {

            }

        });
    }

我如何等待所有回调在此循环中完成然后再进行?

这是我的getSeasonsData方法:

 private void getSeasonsData(String pathString, String childNode, final CallBack3 callBack) {
    fbDB.child(pathString).child(childNode).addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {

            List<UserSeasons> usersSeasonsListTemp = new ArrayList<>();

            if (dataSnapshot.exists()) {

                for (DataSnapshot ds : dataSnapshot.getChildren()) {
                    UserSeasons C = ds.getValue(UserSeasons.class);
                    usersSeasonsListTemp.add(C);
                }
                callBack.onSuccess(usersSeasonsListTemp);

            }

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            callBack.onError(databaseError.getMessage());
        }
    });
}

由于您使用的是Firebase,我认为您需要重新构建查询或数据库。

例如,从fbDB.child(pathString) ,然后可以从返回的快照中获取该路径上的childNode和所有其他子代。 利用listOfUsers的信息,您应该能够过滤快照子级,或累积更大的数据集并返回所需的全部数据,而不用在多个路径上执行多个查询。

原始答案

从理论上讲,您可以有一些int counter = 0; final int userSize = listOfUsers.size() ,然后在回调中的某处放置if语句,以指示何时(i == userSize - 1)表示已处理所有事件。

但是,我建议您的函数应如下所示。 内部化循环。

    getSeasonsData("Seasons", listOfUsers, new Callback() {

        @Override
        public void onSuccess(Map<String, List<UserSeasons>> seasonMap) {
            // Loop over seasonMap  
            // seasons = seasonMap.get(entry.getKey());
            // userSeasons.put(entry.getKey(), seasons);
        }

        @Override
        public void onError(String error) {

        }

    });
}

public void getSeasonsData(String arg1, List arg2, Callback arg3) ,您可以遍历该列表,执行阻止网络调用以添加到某些Map<String, List<UserSeasons>> ,并通过回调从中返回。


您也可以拥有整个Firebase回调,而不是依靠自己的回调。

private void getSeasonsData(String pathString, final ValueEventListener callBack) {
    fbDB.child(pathString).addValueEventListener(callBack);
}

...

// final Map listOfUsers = ... ;
getSeasonsData("Seasons", new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {

        List<UserSeasons> usersSeasonsListTemp = new ArrayList<>();

        if (dataSnapshot.exists()) {

            for (DataSnapshot ds : dataSnapshot.getChildren()) {
                // For example...
                // Object someData = ds.getValue(...);
                // if (listOfUsers.containsKey(someData.getID())) { }

在这里,我删除了第二个参数,因为如果确实需要它,则可以执行"Seasons/" + key因为Firebase支持路径查询字符串

网络呼叫可能会花费一些时间,因此在创建RecycleView适配器之前,您不希望数据准备就绪。 建议您为适配器设置一个空的数据集,然后在onSuccess回调中更新数据集并通知适配器。 您可以通过添加新的方法来更新RecyclerView适配器中的数据集来做到这一点。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM