Android:等待Kotlin协程回调的结果



在我目前的项目中,我正在逐渐从RXJava过渡到协程。我有一种情况,我需要暂停执行并等待回调返回的结果。我已经将我的RXJava方法转换为以以下方式使用协程:

suspend fun fetchProducts(ids: List<String>) = suspendCoroutine<List<ProductItem>> { continuation ->
val getProducts = repo.search(ids, null, null)
getProducts.subscribe(
{ callResult ->
productRequestInProgress.postValue(false)
continuation.resume(callResult.result())
},
{ error ->
productRequestInProgress.postValue(false)
//continuation.resumeWithException(t)
}
)
}

我调用fetchProducts方法从. mapbypage函数,但我得到消息"挂起函数'await'应该只从协程或另一个挂起函数">调用。关于如何正确调用fetchProducts有什么想法吗?函数并等待mapByPage函数的结果?这就是我得到错误消息的地方。由于

val dataSourceFactory = SearcherSingleIndexDataSource.Factory(searcher) { hit ->
Product(hit.json.getValue("id").jsonPrimitive.content)
}.mapByPage { it ->
viewModelScope.launch {
fetchProducts(it.mapNotNull { it.id })
}.await()
}

可以将协程封装在runBlocking块中。

运行一个新的协程并可中断地阻塞当前线程,直到它的完成。

它的设计目的是将常规的阻塞代码与以挂起风格编写的库

.mapByPage { it ->
runBlocking {
fetchProducts(it.mapNotNull { it.id })
}
}

yesawait()被定义为挂起函数,suspend关键字就像一个信号,表明这个函数是一个长时间运行的任务,因此应该异步运行,因为await()是一个挂起函数,如果我们允许在没有程序或其他挂起函数的情况下执行它,这意味着我们正在对错误运行的任务进行阻塞调用,因此我们不允许这样做。

因此挂起函数可以从协程或其他挂起函数中调用,该规则保证长时间运行的任务在挂起函数中不会阻塞主线程。

你也使用启动,你应该使用async功能,而不是launch启动是火和忘记的工作,async是使用当你想要一个结果回来后完成。

一般来说,如果你的suspend函数有一个返回类型,使用async,使用launch,否则

如果你想要一个List的产品返回,你可以使用async,如下所示。

viewModelScope.launch{
val products = viewModelScope.async(Dispathers.Default) { // Dispathers.Default is used for CPU intensive work, even if you don't pass anything Dispathers.Default is there , use Dispacther.IO for IO , Dispathers.Main for working with views in coroutine , like updating text view
fetchProducts(it.mapNotNull { it.id })
}.await()
}

最新更新