在Lambda中调用withContext(Dispatchers.Main)时获取“只能在协程体内调用悬浮函数”

时间:2019-08-02 15:38:46

标签: 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()
}

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

您知道如何在withContext(Dispatchers.Main)上下文中创建的lambda中调用launch吗?

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

谢谢!

2 个答案:

答案 0 :(得分:1)

您可以像这样重写bar函数:

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

答案 1 :(得分:0)


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

private suspend fun foo( coroutineScope: CoroutineScope , lambda : suspend CoroutineScope.() -> Unit)  {
    lambda.invoke(coroutineScope)
}

也喜欢这个


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

private suspend fun foo( coroutineScope: CoroutineScope , lambda : suspend CoroutineScope.() -> Unit)  {
    lambda.invoke(coroutineScope)
}