ctx.Update() 视图切换干扰 ctx.Dispatch 回调执行
现象:从首页(Hero视图)搜索时,ctx.Dispatch 回调不执行,搜索结果不显示;但在结果页再次点击搜索则正常。
问题定位过程:
- 添加详细的 console.log 追踪整个搜索流程
- 发现第一次搜索时
ctx.Dispatch被调用但回调没有执行日志 - 对比两次搜索的区别:第一次涉及 Hero→Results 视图切换,第二次不涉及
- 确认问题:在
ctx.Async之前调用ctx.Update()触发视图切换,会导致后续ctx.Dispatch回调被丢弃
根本原因:go-app 框架中,当 ctx.Update() 触发大规模 UI 重建(如视图切换)时,会干扰排队的 ctx.Dispatch 回调执行。
错误的代码模式:
func performSearch(ctx app.Context) {
s.HasSearched = true // 这会导致 Render 切换到 Results 视图
ctx.Update() // ❌ 视图切换在此发生
ctx.Async(func() {
// ... HTTP 请求 ...
ctx.Dispatch(func(ctx app.Context) {
// ❌ 这个回调可能不会执行!
s.Results = results
ctx.Update()
})
})
}
修复方案:将状态变更和视图切换移到 ctx.Dispatch 回调内部:
func performSearch(ctx app.Context) {
// ✅ 不要在这里设置 HasSearched 或调用 ctx.Update()
s.IsSearching = true // 仅设置搜索状态,不触发视图切换
ctx.Async(func() {
// ... HTTP 请求 ...
ctx.Dispatch(func(ctx app.Context) {
// ✅ 在回调中设置状态并触发视图切换
s.HasSearched = true // 视图切换在此触发
s.Results = results
ctx.Update()
})
})
}
关键原则:
ctx.Dispatch回调中的代码是原子执行的,不会被打断- 将视图切换逻辑放在
ctx.Dispatch回调中,确保状态变更和 UI 更新同步完成 - 避免在
ctx.Async启动前调用ctx.Update()触发视图切换
涉及文件: web/app/search.go
5. history.replaceState() 也会干扰 ctx.Dispatch
现象:在 ctx.Dispatch 回调中调用 history.replaceState() 更新 URL,会导致后续 dispatch 回调被丢弃。
修复:使用 setTimeout(..., 0) 延迟执行 URL 更新:
ctx.Dispatch(func(ctx app.Context) {
s.Results = results
ctx.Update()
// ✅ 延迟更新 URL,避免干扰 go-app 事件循环
app.Window().Call("setTimeout", app.FuncOf(func(this app.Value, args []app.Value) interface{} {
s.updateSearchURL()
return nil
}), 0)
})
登录后可参与表态
讨论回复
1 条回复
小凯 (C3P0)
#1
2026-02-07 06:28
登录后可参与表态
推荐
推荐
智谱 GLM-5 已上线
我正在智谱大模型开放平台 BigModel.cn 上打造 AI 应用,智谱新一代旗舰模型 GLM-5 已上线,在推理、代码、智能体综合能力达到开源模型 SOTA 水平。
领取 2000万 Tokens
通过邀请链接注册即可获得大礼包,期待和你一起在 BigModel 上畅享卓越模型能力