Kotlin在协程中使用Select表达式选择最快结果

2022-12-29 14:08:25 浏览数 (1)

学更好的别人,

做更好的自己。

——《微卡智享》

本文长度为1239,预计阅读4分钟

前言

Kotlin在1.6时增加了Select的表达式,可以同时等待多个挂起函数,并选择第一个可用的。其实就是说在并行的运算中,直接返回最快的结果。

返回最快的结果在哪些场景中应用?

A

其实这个使用的场景也很多,例如我们的APP中获取商品信息,使用串行的方式一般流程是先查找本地数据库,如果没有再请求网络查找信息,而如果改为并行查找,两个同时查找,如果本地存在,速度肯定很快就返回了,不存在也可以快速获取到网络的信息。

再就是像我以前《实测|A*寻路与JPS寻路同一地图运行效率》路径规划算法中,在小的地图里面A*算法和JPS算法速度差不多,而复杂的地图中,JPS要比A*算法快很多倍,所以这里可以直接采用并行处理,获取最快的路径规划。

所以遇到类似这样的情况都可以采用返回最快结果的方式处理。

Select的使用

微卡智享

使用协程中的Select,可以监听async,返回到第一个收到的结果,其架构如下图:

代码

代码语言:javascript复制
package pers.vaccae.channeldemo

import kotlinx.coroutines.*
import kotlinx.coroutines.selects.select


suspend fun getValue(millis: Long): String {
    delay(millis)
    return "Vaccae usetime:${millis}ms"
}

fun main() {
    runBlocking {
        val test1 = async { getValue(100) }
        val test2 = async { getValue(200) }

        val str = select<String> {
            test1.onAwait { rtnvalue -> "test1 ${rtnvalue}" }
            test2.onAwait { rtnvalue -> "test2 ${rtnvalue}" }
        }
        println("str结果:${str}")

        val str2 = select<String> {
            async { getValue(300) }
                .onAwait { rtnvalue -> "test3 ${rtnvalue}" }

            async { getValue(150) }
                .onAwait { rtnvalue -> "test4 ${rtnvalue}" }
        }
        println("str2结果:${str2}")
    }
}

01

壹伴编辑器

定义一个挂起函数,输入参数为等待时间,用于测试优先返回的结果。

02

两次测试

做了两次测试,因为前面的挂起函数返回的是String类型,所以Select<T>泛型就是String类型,我们做了两次测试,第一次输入的延时为100毫秒和200毫秒,第二次是300毫秒和150毫秒,然后我们看一下运行结果。

从上图中可以看到,返回的就是最快的结果,而且用Select的代码非常简洁,如果使用传统的方式,一般会加一个公共变量boolean类型的,先求出结果的修改其boolean值为true,并暂存结果,其余的判断为true后不再输出结果了,这样的方式是求出的最快的返回,但是并行的时间还是要等所有的结果出来,而用Select后可以大大节省时间。

0 人点赞