在客户下拉框里输入「北京」,敲了五个字符发了五次请求,最后停在 bj 的结果上,列表里全是拼音匹配的无关项。乍看像缓存或者权限的锅,追下去往往不是。
let timer, seq = 0;
input.addEventListener('input', e => {
clearTimeout(timer);
const kw = e.target.value.trim();
if (kw.length < 2) return;
timer = setTimeout(async () => {
const id = ++seq;
const list = await search(kw);
if (id === seq) render(list);
}, 300);
});
追下去是这么回事:input 事件每次都直接发请求,没有防抖,也没有丢弃过期响应。先发的慢请求后到,把后发的快结果覆盖了,看起来就是越搜越乱。
「远程搜索防抖」相关的验证我通常做两遍,改完一次、隔天再看一次,确认不是临时生效。接口问题先分清是没发出去、发出去了没收到,还是收到了处理失败。
偶发问题先统计频率,一小时几次和一天一次,查法完全不同。改完顺手把文档补一句,省得下次自己重新推一遍。
具体做法是,输入停 300 毫秒再发请求,输入变化时清掉上一个定时器;给每次请求打序号,回调只认最新那个序号的结果;少于两个字符或关键词没变就直接跳过。
验收就看一点,连续输入五个字符只发出一次请求,列表结果与最后的关键词一致。
