You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LaunchedEffect值捕获时机及两段代码执行结果差异问询

LaunchedEffect的值捕获时机与代码差异解析

核心规则:LaunchedEffect的值捕获逻辑

LaunchedEffect的协程代码块(block)捕获外部值的行为,取决于两个关键因素:

  • 协程启动时机:协程只会在LaunchedEffect首次进入组合,或指定的key发生变化时启动,启动时会捕获当时的外部值。
  • 值的类型:如果捕获的是Compose的状态对象(比如mutableIntStateOf返回的State实例),协程后续访问时会拿到该状态的最新值;如果是普通数据类型(如Int、String),则捕获的是启动时的快照,后续不会自动更新。

两段代码的差异分析

1. MainScreen2中的LaunchedEffect

LaunchedEffect(key1 = Unit, block = {
    delay(5000)
    Log.i("Launcher1", "1: $counter")
})
  • key = Unit:Unit是固定值,所以这个LaunchedEffect只会在MainScreen2首次进入组合时启动一次协程。
  • counter是mutableIntStateOf创建的状态对象:虽然协程启动时counter是0,但延迟5秒后访问counter时,会直接读取该状态对象的当前值。你在1秒内点击三次按钮,counter已经更新为3,所以最终Log输出1: 3。

2. test2中的LaunchedEffect

@Composable
fun test2(count: Int) {
    LaunchedEffect(key1 = true, block = {
        delay(5000)
        Log.i("Launcher", "2: $count")
    })
}
  • key = true:同样是固定值,这个LaunchedEffect只会在test2首次进入组合时启动一次协程。
  • count是普通Int参数:test2首次被调用时,count的值是0,协程启动时直接捕获这个0的快照。后续counter变化导致MainScreen2重组,test2会被重新调用传入新的count,但因为key没变化,旧协程不会被取消或重启,所以延迟5秒后输出的还是最初捕获的0。

验证修改(可选)

如果把test2中的LaunchedEffect的key改成count:

LaunchedEffect(key1 = count, block = {
    delay(5000)
    Log.i("Launcher", "2: $count")
})

每次count变化时,旧协程会被取消,新协程启动并捕获当前的count值。此时点击三次按钮后,最后一次启动的协程会捕获3,延迟5秒后输出2: 3。

内容的提问来源于stack exchange,提问作者Programer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 15:52:32