在继续之前等待多个回调发生

时间:2017-10-25 10:03:07

标签: java android firebase callback

我通过使用在其中具有回调的循环将数据添加到地图。然后我将这张地图传递给Recycler View,但是当我这样做时 - 地图是空的,所以没有显示任何内容。我认为这是因为我需要等待回调发生?

下面的循环位于我的片段中从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());
        }
    });
}

2 个答案:

答案 0 :(得分:0)

由于您使用的是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支持路径查询字符串

答案 1 :(得分:0)

网络调用可能需要一些时间,因此在创建RecycleView适配器之前,您不希望数据准备就绪。我建议您使用空数据集设置适配器,然后在onSuccess回调中更新数据集并通知适配器。您可以通过添加新方法来更新RecyclerView适配器中的数据集来实现此目的。