为何代码未等待Listener执行完成?await失效问题排查
问题原因
port.postMessage()不返回用于等待响应的Promise,await port.postMessage()仅等待消息发送完成(该过程几乎瞬间结束),不会等待监听器收到回复。f函数内没有任何等待监听器接收完消息的逻辑,执行到return语句就结束,外层的await f()自然不会等待消息处理完成。
修复方法
要实现等待监听器收完消息再执行后续逻辑,需要用Promise包裹监听器流程,直到满足“所有消息接收完成”的条件后resolve:
const f = async (leftPaneRowEle, index) => { leftPaneRowEle.scrollIntoView() leftPaneRowEle.children[0].click() console.log('downloadBtn clicked for', leftPaneRowEle) const port = Browser.runtime.connect() // 用Promise等待消息处理完成 await new Promise((resolve) => { const listener = (msg: any) => { console.log('frontend msg:', msg) console.log("BG page received message", msg); // 替换为你的实际判断逻辑:是否已收完所有消息 if (msg.isCompleted || /* 其他完成条件,比如累计接收数量达标 */) { port.onMessage.removeListener(listener) port.disconnect() resolve(true) } } port.onMessage.addListener(listener); port.postMessage({ question: "Can you " + allTFBs[leftpaneindexes[index]] + ":" + desc }) }) } const en: HTMLElement = document.querySelectorAll('#extensionListTable tbody')[0] as HTMLElement const leftPaneRowEle0 = en.children[leftpaneindexes[0]] await f(leftPaneRowEle0, 0) console.log("Done")
注意事项
- 必须根据业务逻辑实现消息完成的判断条件,否则Promise会一直处于pending状态。
- 满足完成条件后,要及时移除监听器并断开端口,避免内存泄漏。
内容的提问来源于stack exchange,提问作者ishandutta2007
相关产品推荐
相关产品推荐

