我感觉我就在这儿附近。
假设我有一个带有 suspendCancellableCoroutine 的方法: (抱歉有任何语法/等错误,只是想弄清楚)
suspend fun foo(): String {
suspendCancellableCoroutine {
val listener = object : Listener {
override fun theThingHappened() {
it.resume("The result")
}
}
// Long involved process
thirdPartyThing.doSomethingWithListener(listener)
}
}
我调用该方法一次,它会执行其操作并返回一个字符串。 但是,如果另一个进程在第一个 CancellableContinuation 仍在运行时调用相同的方法,是否有办法加入它并返回相同的结果?
我问的原因是,在我的 suspendCancellableCoroutine 中,有一个第三方方法只能在任何给定时间运行一次,并且在第一个方法完成之前尝试再次运行它会抛出错误。
假设 foo() 需要 10 秒才能运行。它被调用一次并返回结果字符串。但假设 5 秒后另一个进程调用它。我可以让第二个调用等待第一个调用完成并返回该值吗?
我希望我已经很好地描述了这一点。
假设您保留定义的
foo()
,并创建一个新的公共函数bar()
来执行您的请求。我认为你可以通过将协程 Deferred 存储在属性中来做到这一点。这里的scope
是适合当前类的CoroutineScope。也许它管理自己的,或者外部类将适当的范围传递给它的构造函数。
private val mutex = Mutex()
private var fooDeferred: Deferred<String>? = null
suspend fun bar(): String = mutex.withLock {
fooDeferred ?: scope.async {
foo()
mutex.withLock { fooDeferred = null }
}.also { fooDeferred = it }
}.await()