您可以使用select
,如下所示:
suspend fun doWork(): String = coroutineScope {
select<String> {
async { work1() }.onAwait { it }
async { work2() }.onAwait { it }
}.also {
coroutineContext.cancelChildren()
}
}
在本例中,返回的是String
,但您可以随意更改它,这取决于您的work
返回什么.
如果您正在寻找更多的functional programming
版本,您可以使用raceN
从Arrow
你有这种方法的地方
public suspend inline fun <A, B> raceN(crossinline fa: suspend CoroutineScope.() -> A, crossinline fb: suspend CoroutineScope.() -> B): Either<A, B> =
raceN(Dispatchers.Default, fa, fb)
然后你调用这个raceN
方法
public suspend inline fun <A, B> raceN(
ctx: CoroutineContext = EmptyCoroutineContext,
crossinline fa: suspend CoroutineScope.() -> A,
crossinline fb: suspend CoroutineScope.() -> B
): Either<A, B> =
coroutineScope {
val a = async(ctx) { fa() }
val b = async(ctx) { fb() }
select<Either<A, B>> {
a.onAwait.invoke { Either.Left(it) }
b.onAwait.invoke { Either.Right(it) }
}.also {
when (it) {
is Either.Left -> b.cancelAndJoin()
is Either.Right -> a.cancelAndJoin()
}
}
}