Chrome扩展开发中setTimeout未按设定延迟执行异常问题求助
问题根因
你代码存在2个核心语法错误,不是setTimeout/setInterval本身的问题:
setTimeout(timeoutTrigger(info),15000)写法错误。你直接调用了timeoutTrigger(info),会立即执行该函数,把执行后的返回值(也就是undefined)传给setTimeout,完全没有起到延迟执行的效果。- if判断的逻辑写得不对,
info.error === 'net::ERR_NAME_NOT_RESOLVED' || 'net::ERR_TUNNEL_CONNECTION_FAILED'这段里,后者单独作为布尔值永远为true,意味着只要!info.frameId成立,不管实际错误是什么都会进入逻辑,导致事件被频繁触发,看上去就像是延迟失效了。
修复方案
把setTimeout的第一个参数改为匿名函数包裹需要执行的逻辑,同时修正if判断的错误写法即可。修复后代码如下:
chrome.webNavigation.onErrorOccurred.addListener(info => { if (!info.frameId && (info.error === 'net::ERR_NAME_NOT_RESOLVED' || info.error === 'net::ERR_TUNNEL_CONNECTION_FAILED')) { console.log(info) // 用箭头函数包裹要执行的逻辑,不要直接调用函数 setTimeout(() => timeoutTrigger(info), 15000) } }); function timeoutTrigger(info) { chrome.tabs.update(info.tabId, {url: info.url}); }
额外优化建议
如果要避免同一个tab重复触发多次延迟任务,可以加标记限制同一tab同时只有一个待执行任务:
- 全局定义对象存储待执行的timeoutId:
const tabTimeoutMap = {} - 每次触发前先清掉当前tab之前的timeout:
if(tabTimeoutMap[info.tabId]) clearTimeout(tabTimeoutMap[info.tabId]) - 把新生成的timeoutId存入对象:
tabTimeoutMap[info.tabId] = setTimeout(...) - 延迟逻辑执行完成后删除对应的键值即可。
内容的提问来源于stack exchange,提问作者Mr.Max
相关产品推荐
相关产品推荐

