day26 老板我赶时间,给我最快完成的料理 select

提醒,select仍是实验中的api,请斟酌使用

在这之前的26天,我们所用的都是我要做什麽事,就是做什麽事,不会有条件的选取,但作为android的开发者,一定听过google爸爸说过single trust of source,在架构的最佳化那篇里面,他以最近是否活跃为判断连结

那我这边再多举一个例子,假如你的应用可以离线存取,同时也有客制排序的功能,用户对这项功能的调整频率较低,你可能会选择远端一份排序逻辑资料,本地一份排序逻辑资料

如果是用户自己设置,你可以在设置确认後先发到远端,在更新本地,如果是slope one的算法你可以考虑用workManager去定时fetch等等,在多种情境下我们会做不同的考量,而我这里在系列文里最後介绍一个coroutine的工具,select

中文好像叫多路复用,其实他就是会先拿到最早available的值

viewModelScope.launch {
    val orderRule = select<OrderResponse<OrderRule>> {
        async { localOrder() }.onAwait{ OrderResponse(it, isLocal = true)}
        async { remoteOrder() }.onAwait{ OrderResponse(it, isLocal = false) }
    }
}

channel

不知道channel的人转这里

而select也可以接收多个channel,通常我们一个channel是可以由多个priducer和多consumer对吧

但如果需求是要同时接收不同的channel呢? 最适合的工具就是select了

suspend fun selectFizzBuzz(fizz: ReceiveChannel<String>, buzz: ReceiveChannel<String>) {
    select<Unit> { // <Unit> 意味着该 select 表达式不返回任何结果
        fizz.onReceive { value ->  // 这是第一个 select 子句
            println("fizz -> '$value'")
        }
        buzz.onReceive { value ->  // 这是第二个 select 子句
            println("buzz -> '$value'")
        }
    }
}
val fizz = fizz()//启动一个corotine,每0.3秒丢值
val buzz = buzz()//启动一个corotine,每0.5秒丢值
repeat(7) {
    selectFizzBuzz(fizz, buzz)
}//蒐集7个
coroutineContext.cancelChildren() //取消两个coroutine

文档给的范例非常简单,我也就不多加叙述了

那如果蒐集到已经close的channel要怎麽半?

onReceive会throw Exception,但我们可以用onReceiveOrNull,如果channel close他会回传null,而我们可以再对此作处理

b.onReceiveOrNull { value -> 
    if (value == null) 
        "Channel 'b' is closed"
    else    
        "b -> '$value'"
}

而channel的接收和发送都会suspend,select也能对发送做出处理

fun CoroutineScope.produceNumbers(side: SendChannel<Int>) = produce<Int> {
    for (num in 1..10) { // 生产从 1 到 10 的 10 个数值
        delay(100) // 延迟 100 毫秒
        select<Unit> {
            onSend(num) {} // 发送到主通道
            side.onSend(num) {} // 或者发送到 side 通道
        }
    }
}

大概酱,因为再channel的consume那边,可能会执行其他动作,这时select救苦以尽快将值发给已经可以此用的channel里面

其实select是个比较少用到的功能,但听我讲讲你也不吃亏,先有个概念,未来遇到问题时也能很快联想到这个解法,今天就这样,掰掰

连结

必看

文档

选看

别人讲的
别人讲的


<<:  Day27_CSS语法10

>>:  Day 29 - 这个游戏制作人疯了吧

将机器人部属到网路上去

开始部属 点击 登入後会看到这个画面 点击左上方的加号 进行第一次的线上coding 在main上输...

[13th][Day19] http request header(上)

golang 服务 常用於 http server/ http client 来看看一张厉害的图儿 ...

登录档的增删改查--风险技能平民都会

今天迈入第7天,根据计画,前几天我们介绍了一些登录档的基础知识和前置作业,假设读者跟笔者一样略懂略懂...

Day 27 - WooCommerce: 建立虚拟帐号付款订单

铁人赛进入尾声了,和大家分享个好消息,这支 WordPress 付款外挂已经写好送审到 WordPr...

D22/ 怎麽在 Compose 中用 Material Theme? - Theme

今天大概会聊到的范围 Theme 透过 Android Studio 内建的精灵建立一个新的 Co...