news 2026/7/13 15:52:00

ArkTS 搜索旧请求覆盖新结果怎么办:中式美食输入框怎么防止慢请求回写

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ArkTS 搜索旧请求覆盖新结果怎么办:中式美食输入框怎么防止慢请求回写

ArkTS 搜索旧请求覆盖新结果怎么办:中式美食输入框怎么防止慢请求回写

中式美食的搜索框不是等用户输入完才有动作。用户可能连续输入“番”“番茄”“番茄炒蛋”,也可能一边删一边改。如果每次输入都发一次查询,旧请求不一定先回来。最常见的现象是:输入框已经是“番茄炒蛋”,列表却显示“番”的结果。

这个问题不要只靠防抖。防抖能减少请求次数,但不能保证慢请求不会最后回来。我的做法是加一个requestVersion,每次发请求都带版本号,只有最新版本能回写页面。

本文导读

问题处理方式
快速输入后结果乱跳每次搜索递增 requestVersion
慢请求覆盖新结果回写前比较版本号
清空输入框仍显示旧结果清空时也递增版本并回到默认列表
搜索失败后页面乱保留关键词,单独显示错误态

环境和文件边界

项目内容
开发工具DevEco Studio
HarmonyOS SDKAPI 12,Stage 模型
搜索页entry/src/main/ets/features/search/SearchPage.ets
状态层entry/src/main/ets/features/search/SearchViewModel.ets
数据层entry/src/main/ets/data/repository/RecipeSearchRepository.ets
本文重点ArkTS 搜索请求时序、旧请求拦截、RDB 查询

错误写法:谁回来晚谁覆盖

asynconKeywordChange(keyword:string):Promise<void>{this.keyword=keywordthis.loading=truethis.result=awaitthis.repository.search(keyword)this.loading=false}

这段代码最大的问题是没有判断“这个结果是不是当前输入框想要的结果”。请求 A 搜“番”,请求 B 搜“番茄炒蛋”。如果 B 先回来,页面显示正确;A 后回来,又把列表覆盖成旧结果。

用 requestVersion 拦住旧回写

exportclassSearchViewModel{privaterequestVersion:number=0keyword:string=''loading:boolean=falseerrorText:string=''result:RecipeCard[]=[]asyncsearch(keyword:string):Promise<void>{constversion=++this.requestVersionthis.keyword=keywordthis.loading=truethis.errorText=''try{constrows=awaitthis.repository.searchRecipe(keyword)if(version!==this.requestVersion)returnthis.result=rows}finally{if(version===this.requestVersion){this.loading=false}}}}

这个版本号不是为了炫技,就是一个很朴素的判断:你回来时,如果已经不是最新请求,就不要改页面。

清空输入框也要当成一次新请求

asyncclearKeyword():Promise<void>{constversion=++this.requestVersionthis.keyword=''this.errorText=''this.loading=falsethis.result=awaitthis.repository.queryDefaultRecommend()if(version!==this.requestVersion){return}}

清空输入框容易被忽略。用户点清空后,旧搜索请求如果还在路上,回来以后会把默认推荐覆盖掉。所以清空也要递增版本。

Repository 只负责查,不负责决定能不能回写

exportclassRecipeSearchRepository{asyncsearchRecipe(keyword:string):Promise<RecipeCard[]>{constkey=keyword.trim()constpredicates=newrelationalStore.RdbPredicates('recipe')predicates.like('search_text',`%${key}%`)predicates.orderByDesc('score')predicates.orderByDesc('updated_at')predicates.limitAs(30)constrows=awaitthis.queryRows(predicates)returnrows.map(row=>this.toRecipeCard(row))}}

Repository 不需要知道输入框现在是什么。它只负责把某个关键词查出来。能不能回写,是 ViewModel 的职责。

页面层只绑定状态

@Componentexportstruct SearchPage{@StateviewModel:SearchViewModel=newSearchViewModel()build(){Column(){SearchInput({value:this.viewModel.keyword,onChange:(value:string)=>this.viewModel.search(value),onClear:()=>this.viewModel.clearKeyword()})SearchResultList({loading:this.viewModel.loading,errorText:this.viewModel.errorText,recipes:this.viewModel.result})}}}

页面层不要再自己判断旧请求。它只要把输入动作交给 ViewModel,然后根据 ViewModel 状态渲染。

防抖可以加,但不是唯一防线

exportclassSearchDebouncer{privatetimer:number=0run(task:()=>void,delay:number=250):void{if(this.timer>0){clearTimeout(this.timer)}this.timer=setTimeout(task,delay)}}

防抖的作用是少发请求,requestVersion的作用是防止旧请求回写。两个解决的是不同问题,不要把它们混成一个。

回归验收记录

步骤操作预期
1快速输入“番”“番茄”“番茄炒蛋”最终只显示最后一个关键词结果
2人为延迟第一个请求旧请求返回后不能覆盖新列表
3清空输入框回到默认推荐,不保留旧搜索结果
4搜索失败保留关键词和错误态,不乱写空结果
5切换分类再搜索requestVersion 重新生效
6返回搜索页输入框和结果保持一致

排查顺序

顺序先看什么为什么先看它
1请求返回前有没有版本判断没有判断就会被旧请求覆盖
2清空输入是否递增版本清空也可能被旧请求回写
3loading 是否按版本关闭旧请求不能把新请求的 loading 关掉
4防抖和版本号是否同时存在防抖减少请求,版本号保证正确

边界责任

层级应该负责什么不应该负责什么
SearchPage绑定输入框和结果列表判断哪个请求有效
SearchViewModel维护 requestVersion 和页面状态拼复杂 SQL
Repository根据关键词查 RDB决定是否回写页面
Debouncer减少输入触发频率替代请求版本判断

小结

搜索页最怕的是“输入框和结果不一致”。用户看到这种错乱,会直接怀疑搜索功能不可信。

中式美食这里我会把时序控制放在 ViewModel:输入变化递增版本,请求返回前比较版本,清空输入也递增版本。Repository 只查数据,页面只渲染状态。这样即使网络慢、用户输入快,旧请求也不能把新结果覆盖掉。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/13 15:50:46

3 种混合波束成形方案对比:传统优化 vs 深度学习 vs 深度强化学习

混合波束成形技术路线深度对比&#xff1a;传统优化、深度学习与深度强化学习在毫米波通信和大规模MIMO系统中&#xff0c;混合波束成形&#xff08;Hybrid Beamforming, HBF&#xff09;技术通过结合模拟和数字域处理&#xff0c;在系统性能和硬件复杂度之间实现了关键平衡。本…

作者头像 李华
网站建设 2026/7/13 15:49:39

Lumino部署与打包:从开发到生产的完整工作流程

Lumino部署与打包&#xff1a;从开发到生产的完整工作流程 【免费下载链接】lumino Lumino is a library for building interactive web applications 项目地址: https://gitcode.com/gh_mirrors/lu/lumino 想要构建高性能的交互式Web应用程序&#xff1f;Lumino作为Ju…

作者头像 李华
网站建设 2026/7/13 15:47:04

JavaString知识梳理

作者&#xff1a;没有四次元口袋的蓝胖 日期&#xff1a;2026-07-12 标签&#xff1a;Java, StringJava String知识梳理 一、String 的不可变性 String 是不可变的&#xff08;immutable&#xff09;&#xff0c;一旦创建&#xff0c;其值就不能修改。 1.1 为什么设计成不可变&…

作者头像 李华
网站建设 2026/7/13 15:47:00

C# Task WaitAll、WaitAny、WhenAll、WhenAny

笔记承接&#xff1a;承接Task获取异步结果笔记&#xff0c;本节课核心四大方法&#xff1a;WaitAll、WaitAny、WhenAll、WhenAny核心区分&#xff1a;带Wait开头同步阻塞&#xff1b;带When开头异步非阻塞&#xff1b;搭配任务工厂回调&#xff0c;补齐限时等待用法窗体控件&a…

作者头像 李华