在 lambda 中调用 withContext(Dispatchers.Main) 时获取“只能在协程主体内调用暂停函数”

Ped*_*rim 19 kotlin kotlin-coroutines

我正在使用下面的脚本创建一个协程:

fun bar(completion: () -> Unit) {
  GlobalScope.launch(Dispatchers.IO) {
    val lambda = {
      withContext(Dispatchers.Main) { //Suspension functions can be called only within coroutine body
        completion()
      }
    }
    foo(lambda)
  }
}

fun foo(lambda: () -> Unit) {
  //...do something heavy
  lambda()
}
Run Code Online (Sandbox Code Playgroud)

但是Suspension functions can be called only within coroutine body当我调用时出现错误,withContext(Dispatchers.Main)因为 lambda 更改了上下文。我无法更改foo(lambda: () -> Unit)为,foo(lambda: suspend () -> Unit)因为它来自外部库。

知道我可以withContext(Dispatchers.Main)launch上下文中创建的 lambda 内部调用什么吗?

  • 科特林版本:1.3.41
  • 协程:1.3.0-RC

谢谢!

And*_*ana 7

你可以bar像这样重写你的函数:

fun bar(completion: () -> Unit) {
    GlobalScope.launch(Dispatchers.IO) {
        suspendCoroutine<Unit> {
            val lambda = {
                it.resume(Unit)
            }
            foo(lambda)
        }
        withContext(Dispatchers.Main) {
            completion()
        }
    }
}

Run Code Online (Sandbox Code Playgroud)

  • 这个解决方案的解释是什么? (25认同)
  • 如果没有解释,这个答案毫无用处 (12认同)
  • 太棒了,这太棒了!从解释的角度来看,协程必须手动挂起并从回调中恢复,因为回调不支持协程。通过这种方式,您可以发出信号,表明您已准备好从非协程代码块(即:回调)继续协程 (2认同)