|
@@ -230,5 +230,40 @@ suspend fun <T, R> CoroutineScope.fastest(vararg deferredArray: DeferredTransfor
|
|
|
return chan.receive()
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * 该函数将选择[deferredList]中的Deferred执行[Deferred.await], 然后将返回最快的结果
|
|
|
+ * 执行过程中的异常将被忽略, 如果全部抛出异常则将抛出最后一个Deferred的异常
|
|
|
+ *
|
|
|
+ * @see DeferredTransform 允许监听[Deferred]返回数据回调
|
|
|
+ * @param deferredList 一系列并发任务
|
|
|
+ */
|
|
|
+@OptIn(ExperimentalCoroutinesApi::class)
|
|
|
+@Suppress("SuspendFunctionOnCoroutineScope")
|
|
|
+suspend fun <T, R> CoroutineScope.fastest(deferredList: List<DeferredTransform<T, R>>): R {
|
|
|
+ val chan = Channel<R>()
|
|
|
+ val mutex = Mutex()
|
|
|
+ deferredList.forEach {
|
|
|
+ launch(Dispatchers.IO) {
|
|
|
+ try {
|
|
|
+ val result = it.deferred.await()
|
|
|
+ mutex.withLock {
|
|
|
+ NetCancel.cancel(coroutineContext[CoroutineExceptionHandler])
|
|
|
+ if (!chan.isClosedForSend) {
|
|
|
+ val transformResult = it.block(result)
|
|
|
+ chan.send(transformResult)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (e: Exception) {
|
|
|
+ it.deferred.cancel()
|
|
|
+ val allFail = deferredList.all { it.deferred.isCancelled }
|
|
|
+ if (allFail) throw e else {
|
|
|
+ if (e !is CancellationException) e.printStackTrace()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return chan.receive()
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
|