Chrome扩展MV3中runtime.sendMessage异步响应返回失败问题求助
Chrome Manifest V3 异步消息返回失败问题解决
问题根因
你代码的核心问题是 chrome.runtime.onMessage 的监听器被声明为了 async 函数:
async函数的返回值默认是Promise对象,你代码中写的 return true 会被自动包装为 Promise.resolve(true),Chrome的消息监听逻辑判断不到原生布尔值true,就会认为你不需要异步返回响应,同步代码执行完毕后直接关闭消息端口,等你await异步逻辑结束再调用sendResponse时,端口已经被销毁,sendResponse也被垃圾回收,自然无法返回结果给content script。
你看到的「The message port closed before a response was received」报错就是这个原因导致的。
修复方案
方案1:使用.then链式调用处理异步逻辑
不要将监听器本身声明为async,直接用Promise的then方法处理异步结果,同步返回true即可:
// background.js 修改后代码 chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => { if (msg.message == "Please Respond") { myTestPromise().then(testMessage => { console.log(testMessage) sendResponse({response:testMessage}) }) } return true; });
方案2:将异步逻辑包装在立即执行函数(IIFE)中
如果习惯用async/await写法,可以把异步逻辑包在独立的async立即执行函数里,监听器本身保持为普通同步函数,正常返回true:
// background.js 修改后代码 chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => { if (msg.message == "Please Respond") { // 异步逻辑放在独立的IIFE中,不影响监听器本身的返回值 (async () => { const testMessage = await myTestPromise(); console.log(testMessage) sendResponse({response:testMessage}) })() } return true; });
拓展优化:content script 支持Promise写法
Manifest V3的chrome.runtime.sendMessage原生支持Promise调用,不需要写回调函数,写法更简洁:
// mORS.js 可选优化写法 (async () => { try { const response = await chrome.runtime.sendMessage({ message: "Please Respond" }); console.log(`Response:`, response) if (response.response == "Success") { console.log("Success!") } } catch (error) { console.log(error) } })()
术语补充说明
你之前疑惑的「垃圾回收」在这里特指:Chrome如果判断不需要异步响应,会自动销毁sendResponse回调函数,释放相关内存,后续再调用该函数不会产生任何效果。
内容的提问来源于stack exchange,提问作者Bobby
相关产品推荐
相关产品推荐

