【问题标题】:Realtime Database how to wait for asynchronous task in iteration?实时数据库如何在迭代中等待异步任务?
【发布时间】:2021-01-24 15:01:28
【问题描述】:

我在这里所做的是将用户组作为哈希图,然后获取每个组的信息并用它做其他事情。但在 foreach 循环结束时,我的“组”列表为空。我能做些什么来等待 foreach 循环完成吗?谢谢。

db
    .child("users")
    .child(firebaseUser.uid)
    .get()
    .addOnCompleteListener { task ->
        if (task.isSuccessful) {
        val document = task.result

        if (document != null && document.value != null) {
            val groupsObject =
                document.value["groups"] as HashMap<String, Boolean>

            for (groupID in groupsObject.keys) {
                db
                    .child("groups/$groupID")
                    .addValueEventListener(object : ValueEventListener {
                        override fun onDataChange(snapshot: DataSnapshot) {
                            db
                                .child("users")
                                .child(friendID)
                                .get()
                                .addOnCompleteListener { task ->
                                    // check for something
                                    // add to groups list if data is OK
                                }
                        }

                        override fun onCancelled(error: DatabaseError) {
                            // TODO: ...
                        }
                    })
            }

            // here "groups" data is empty, because that for each loop above
            // hasn't finshed yet looping, and thus my list is displayed empty
            groupsAdapter = GroupsAdapter(this@GroupsActivity, groups)
            recyclerView.adapter = groupsAdapter
        }
    }
}

【问题讨论】:

    标签: android kotlin firebase-realtime-database


    【解决方案1】:

    没有办法在不阻止用户使用您的应用的情况下等待所有数据加载完毕。这就是为什么经验法则总是相同的:任何需要数据库数据的代码都需要在addOnCompleteListener 回调中,或者从那里调用。


    惯用的方法是不等待数据加载,而是在新数据进入时告诉适配器。您可以通过在 addOnCompleteListener 中调用 notifyDataSetChanged 来做到这一点:

    db
        .child("groups/$groupID")
        .addValueEventListener(object : ValueEventListener {
            override fun onDataChange(snapshot: DataSnapshot) {
                db
                    .child("users")
                    .child(friendID)
                    .get()
                    .addOnCompleteListener { task ->
                        // check for something
                        // add to groups list if data is OK
                        groupsAdapter.notifyDataSetChanged()
                    }
            }
    

    如果您确实必须在所有数据加载后运行一些代码,一种常见的方法是保留一个您已经加载的好友数量的计数器,并在addOnCompleteListener 中检查该数量。

    比如:

    .addOnCompleteListener { task ->
        // check for something
        // add to groups list if data is OK
        
        if (friendsLoadedCount++ === groupsObject.keys.size()) {
            // TODO: all friends have loaded, so do something with them
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-18
      • 2016-07-24
      • 2013-02-10
      • 2017-07-22
      相关资源
      最近更新 更多