0

我正在使用实时数据。我想在 IO 中运行一些任意代码,然后在完成后,在主线程中运行一些任意代码。

在 JavaScript 中,您可以通过将 Promise 链接在一起来完成类似的事情。我知道 Kotlin 是不同的,但这至少是我理解的一个框架。

我有一个函数,有时会从 Main 调用,有时会从 IO 调用,但它本身不需要特殊的 IO 功能。从内部class VM: ViewModel()

private val mState = MyState() // data class w/property `a`
val myLiveData<MyState> = MutableLiveData(mState)

fun setVal(a: MyVal) {
    mState = mState.copy(a=a)
    myLiveData.value = mState
}

fun buttonClickHandler(a: MyVal) {
    setVal(a) // Can execute in Main
}

fun getValFromDb() {
    viewModelScope.launch(Dispatchers.IO) {
        val a: MyVal = fetchFromDb()
        setVal(a) // Error! Cannot call setValue from background thread!
    }
}

在我看来,显而易见的方法是val a = fetchFromDb()从 IO 执行,然后setVal(a)退出该块并进入 Main。

有没有办法做到这一点?我看不出这个功能不存在的概念性原因。有没有什么想法

doAsyncThatReturnsValue(Dispatchers.IO) { fetchFromDb()}
    .then(previousBlockReturnVal, Dispatchers.Main) { doInMain() }

可以在 ViewModel 中运行?

请在上面适当的地方用“coroutine”替换“thread”。:)

4

1 回答 1

3

发射很好。您只需要切换调度程序并使用withContext

fun getValFromDb() {
    // run this coroutine on main thread
    viewModelScope.launch(Dispatchers.Main) {
        // obtain result by running given block on IO thread
        // suspends coroutine until it's ready (without blocking the main thread)
        val a: MyVal = withContext(Dispatchers.IO){ fetchFromDb() }
        // executed on main thread
        setVal(a) 
    }
}
于 2019-09-27T19:23:33.530 回答