网站首页 > 技术文章 正文
在前端开发中,搜索框的实时搜索功能是一个常见场景。用户输入文字时,每输入一个字符就发起搜索请求。但这里存在一个潜在的竞态问题:如果后发起的请求比先发起的请求更快返回,可能会导致错误的搜索结果显示。防抖能一定程度减少竞态问题的出现,但是无法杜绝。
竞态问题示例
假设用户快速输入"ab":
- 输入"a"时发起请求A
- 输入"b"时发起请求B
- 请求B先返回,显示"ab"的结果
- 请求A后返回,错误地覆盖为"a"的结果
乐观锁解决方案
我们可以借鉴后端乐观锁的机制来解决这个问题: #技术分享
复现竞态问题示例
加锁解决竞态问题示例
架构图
源码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>竞态问题搜索示例</title>
<style>
# results {
margin-top: 20px;
border: 1px solid #ccc;
padding: 10px;
min-height: 100px;
}
</style>
</head>
<body>
<h1>竞态问题搜索示例</h1>
<input type="text" id="searchInput" placeholder="输入搜索内容..." />
<div id="results">搜索结果将显示在这里</div>
<script>
let requestVersion = 0
async function mockSearchApi(query) { const delay = 1000 - query.length * 200 await new Promise((resolve) => setTimeout(resolve, delay)) return `查询"${query}"的结果,延迟${delay}ms` }
async function raceSafeSearch(query) { const currentVersion = ++requestVersion
try { const response = await mockSearchApi(query) if (currentVersion === requestVersion) { document.getElementById('results').textContent = response console.log(`显示结果: ${response}`) } else { console.log(`忽略过时结果: ${response} (当前版本: ${requestVersion}, 请求版本: ${currentVersion})`) } } catch (error) { console.error('搜索出错:', error) } } document.getElementById('searchInput').addEventListener('input', (e) => { const query = e.target.value.trim() query && raceSafeSearch(query) }) </script>
</body>
</html>
实现原理
- 全局版本号 : requestVersion 是一个递增的计数器,每次发起新请求时递增
- 请求捕获 :每次发起请求前,保存当前的 currentVersion
- 响应验证 :当响应返回时,检查 currentVersion 是否等于最新的 requestVersion
- 如果相等,说明这是最新的请求结果,可以显示
- 如果不相等,说明已有更新的请求发出,忽略此结果
- 优化 :实际使用还可以加上防抖,减少不必要的请求丢弃。
总结
通过这种乐观锁机制,确保了只有最后一次请求的结果会被显示,有效解决了前端搜索中的竞态问题。这种方法简单高效,不需要复杂的状态管理,适用于大多数异步场景下的竞态问题处理。
猜你喜欢
- 2025-09-28 面试字节跳动被问到这个问题:如何用Hadoop或者Spark来解决TopN
- 2025-09-28 某公司程序员每天划水,为何绩效反而更高?原来每天都专门写BUG
- 2024-12-22 77% 的 Linux 运维都不懂的内核问题,这篇全告诉你了
- 2024-12-22 男科不及格?这种舌头前端塌陷的舌象,问题在肺不在肾!
- 2024-12-22 啥?线上css样式错乱了?我本地运行没问题啊!
- 2024-12-22 使用Axios 拦截器解决「 前端并发冲突 」 问题
- 2024-12-22 前端面试常见问题 有使用过vue吗?说说你对vue的理解
- 2024-12-22 web前端54道题面试题的问题集合 2020web前端面试题
- 2024-12-22 前端既然已经内卷了,为什么公司还是招不到人?问题在哪?
- 2024-12-22 礼县纪委:抓好“前端”工作 着力发现问题
你 发表评论:
欢迎- 09-28前端同学狂喜_前端gui
- 09-28默认选择 React,等于是在扼杀前端创新
- 09-28《前端研发规范》+配置文件_前端开发规范
- 09-28JavaScript 常用事件大全:从基础到实战应用
- 09-28快看!百度提前批的面试难度,你能拿下吗?
- 09-28找工作速看!今日最新热招岗位全曝光
- 09-28Vue3+ElementPlus 免费后台管理模板VueNextAdmin
- 09-28前端开发的物理外挂来了,爽到飞起!
- 最近发表
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端aes加密 (58)
- 前端脚手架 (56)
- 前端md5加密 (54)
- 前端路由 (61)
- 前端数组 (73)
- 前端js面试题 (50)
- 前端定时器 (59)
- Oracle RAC (76)
- oracle恢复 (77)
- oracle 删除表 (52)
- oracle 用户名 (80)
- oracle 工具 (55)
- oracle 内存 (55)
- oracle 导出表 (62)
- oracle约束 (54)
- oracle 中文 (51)
- oracle链接 (54)
- oracle的函数 (58)
- oracle面试 (55)
- 前端调试 (52)
本文暂时没有评论,来添加一个吧(●'◡'●)