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

Luau协程执行停滞问题:自制OnChange事件监听器遇阻塞

问题原因分析与解决办法

核心问题1:值传递导致内部变量无法感知外部修改

Lua里数字这类基本类型是值传递,你调用Changed(n)时,函数里的Value只是外部n的一个副本,和原变量完全独立。后面你修改n = n+1,根本不会影响Changed函数里的Value,所以StartingValue ~= Value永远不成立,while true无限循环,协程直接卡在这里,主程序的后续代码完全没机会执行。

核心问题2:协程没有让出执行权的机会

就算解决了值传递的问题,你的Changed函数循环里也没有调用coroutine.yield(),一旦进入循环就会霸占执行权,主程序还是没法运行修改操作。


修正后的代码示例

用table包装变量实现引用传递,同时在循环里让出执行权:

function Changed(ref)
    local StartingValue = ref.value
    while true do
        if StartingValue ~= ref.value then
            print(ref.value)
            StartingValue = ref.value
            -- 如果要持续监听可以去掉break,这里保留原逻辑只触发一次
            -- break
        end
        coroutine.yield() -- 让出执行权,让主程序有机会修改值
    end
end

local n = {value = 0} -- 用table包装,实现引用传递
local co = coroutine.wrap(function()
    Changed(n)
end)

co() -- 第一次执行协程,进入循环后yield

n.value = n.value + 1
co() -- 再次唤醒协程,检查到值变化

print("Script ended")

修正说明

  1. 用{value = 0}包装变量:Lua里table是引用传递,函数内部读取/修改table属性会直接影响外部的table。
  2. 加入coroutine.yield():每次循环都主动让出执行权,让主程序能修改变量,之后再唤醒协程检查变化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 15:15:27