当前位置: 首页 > 知识库问答 >
问题:

如果coroutine的延迟类型为null,会发生什么情况?

濮丰
2023-03-14

我在代码中使用了嵌套的Coroutine块。当我试图将Deferredtype的结果转换为变量时,得到了一个空值。因此,它导致了一个转换问题,即kotlin.TypeCastException:null不能转换为getNearbyHealthInstitutions()方法返回行中的非空类型kotlin.Collections.ArrayList。我相信,我在某个时候做了正确的实现,但是我错过了什么从Deferred的结果中得到空值?有趣的是,当我调试它时,它确实返回了预期的值。我想应该是并发问题,或者我不知道为什么它在调试模式下工作。伙计们,有什么主意吗?

// Invocation point where resides in a callback
GlobalScope.launch(Dispatchers.Main) {
    nearbyHealthInstitutionSites.value = getNearbyHealthInstitutions()
}

private suspend fun getNearbyHealthInstitutions(radius: Meter = DEFAULT_KM_RADIUS) : ArrayList<Hospital> {
    return CoroutineScope(Dispatchers.IO).async {
        val list = getHealthInstitutions()
        val filteredList = list?.filter { it.city == state?.toUpperCase() } as MutableList<Hospital>
        Log.i(MTAG, "nearby list is $filteredList")
        Log.i(MTAG, "nearby list's size is ${filteredList.size}")

        var deferred: Deferred<MutableList<Hospital>>? = null

        addAllNearbyLocations(onEnd = { nearbyHealthInstitutions ->
            deferred = async {
                findNearbyOfficialHealthInstitutions(
                    officialHealthInstitutionList = filteredList as ArrayList<Hospital>,
                    nearbyHealthInstitutions = nearbyHealthInstitutions
                )
            }
        })

        val result = deferred?.await()

        return@async result as ArrayList<Hospital>
    }.await()
}

private suspend fun findNearbyOfficialHealthInstitutions(officialHealthInstitutionList: ArrayList<Hospital>, nearbyHealthInstitutions: MutableList<Hospital>): MutableList<Hospital> {
        return GlobalScope.async(Dispatchers.Default) {
            val result = mutableListOf<Hospital>()

            officialHealthInstitutionList.forEach {
                nearbyHealthInstitutions.forEach { hospital ->
                    StringSimilarity.printSimilarity(it.name, hospital.name)

                    val similarity = StringSimilarity.similarity(it.name, hospital.name.toUpperCase())

                    if (similarity > SIMILARITY_THRESHOLD) {
                        Log.i(MTAG, "findNearbyOfficialHealthInstitutions() - ${it.name} and ${hospital.name.toUpperCase()} have %$similarity")
                        result.add(hospital)
                    }

                }
            }

            Log.i(TAG, "------------------------------------------")
            result.forEach {
                Log.i(MTAG, "findNearbyOfficialHealthInstitutions() - hospital.name is ${it.name}")
            }

            return@async result
        }.await()
    }

共有1个答案

孟佑运
2023-03-14

由于AddAllNearbyLocations()是异步的,您的coroutine需要等待调用回调以继续执行。您可以为此使用suspendcoroutineAPI。

val result = suspendCoroutine { continuation ->
    addAllNearbyLocations(onEnd = { nearbyHealthInstitutions ->
          findNearbyOfficialHealthInstitutions(
                officialHealthInstitutionList = filteredList as ArrayList<Hospital>,
                nearbyHealthInstitutions = nearbyHealthInstitutions
          ).let { found -> continuation.resume(found) }
    })
}

另外,您应该使用list而不是arraylistmutablelist,您应该始终使用泛型接口,而不是该接口的特定实现。这也得到了一些铸件的rids(理想情况下,在此代码中不应该有铸件)。

 类似资料:
  • 问题内容: 线程启动后,如果该线程的引用设置为,那么该线程将如何处理?会停止吗?它有资格获得GC吗? 像这样: 问题答案: 实时线程将继续运行,即使其引用设置为null。 就像任何其他对象一样,当没有任何引用时,它就有资格使用GC。棘手的一点是,即使您的程序未保留一个 正在运行的线程 在ThreadGroup中的引用,因此 也永远不会 对 正在运行的线程进行GC。

  • 我目前正在一个项目中从RxJava切换到Kotlin coroutines,用coroutine含水层替换所有单一和可观察的返回类型。我仍然在为以下结构而挣扎:一个接口(例如存储库的接口)提供数据查询访问并返回一个RxJava single。该实现使用Single.Create创建单个对象,并使用onSuccess/onError发出结果。现在,实现检索数据所需要做的是创建一个带有回调的侦听器,并

  • 我看到,如果在活动中实例化Dagger 2组件,那么稍后在方法中将其置空,如图所示。 如果我不该实例会发生什么,会发生什么? 旁注:在评论中,我发现了一个有用的提示,为什么人们会将其设置为,这很有说服力:“我认为这没有必要,但它定义的范围非常清楚”。

  • 问题内容: 因此,当我发现一些非常奇怪的东西时,我正在使用Node.js REPL和Underscore库。如果I ,则该变量是全局设置的(显然)。然后,当我尝试运行一个简单的命令时,它会打印出来(显然,再次)。但是,此后立即运行,因为变量设置为,它会打印。 为什么这样做呢?如果我从js文件运行相同的代码,则不会发生。这是正常的Node事情,还是全部错误? 仅供参考:节点v0.10.10 问题答案

  • 根据Java教程 将包装类型(整数)的对象转换为其相应的基元(int)值称为取消装箱。当包装类的对象为: 作为参数传递给需要相应基元类型的值的方法 分配给相应基元类型的变量 为什么在这种情况下会发生拆箱? 在这种情况下,这些事情发生在哪里?是否有管理数组中元素访问的底层方法?或者[]暗示某种变量?

  • 问题内容: 我需要在循环中对数据库进行SQL查询: 更好的方法是:保持原样或循环后移动: 或者是其他东西 ? 问题答案: 整个要点是直到函数返回才执行,因此将其放置在要关闭的资源打开后的适当位置。但是,由于要在循环内创建资源,因此根本不要使用defer- 否则,在函数退出之前,您不会关闭在循环内创建的任何资源,因此它们会堆积直到然后。相反,您应该在每次循环迭代结束时关闭它们, 而无需 :