JavaScript Promise未同步执行,chrome.storage.local.get返回undefined求助
你遇到的问题核心在于 chrome.runtime.onMessage 的异步处理规则:当你在监听器里需要异步调用 sendResponse 时,必须让监听器函数返回 true,否则浏览器会在监听器同步代码执行完毕后立刻关闭消息通道,导致后续异步完成时调用 sendResponse 无法把数据正确传递出去。
从你的控制台输出也能看出来:异步获取到的数据是正确的("[{\"word\":\"mo\",\"color\":\"rgb(128,0,128)\",\"id\":\"0\"}]"),但发送给popup的却是undefined——这就是因为消息通道提前关闭了,sendResponse 没有生效。
修正后的代码
我们只需要在监听器里添加 return true;,同时可以优化一下Promise的写法(Chrome现在支持用chrome.storage.local.get的Promise版本,不用手动封装):
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) { if( request.message === "fetch-local-storage" ){ // 使用Chrome API原生的Promise版本(更简洁) chrome.storage.local.get('localSearchList') .then(result => { const responseData = result.localSearchList; sendResponse({ message: "local-storage-data", data: JSON.stringify(responseData) }); }) .catch(err => { // 可以添加错误处理 sendResponse({message: "error", data: err.message}); }); // 关键:返回true保持消息通道打开,直到sendResponse被调用 return true; } });
额外说明
为什么要返回true?
Chrome的消息机制规定:如果监听器要异步调用sendResponse,必须返回true来告知浏览器“我之后会调用sendResponse,先别关通道”。如果不返回true,浏览器会认为监听器已经处理完消息,直接关闭通道,后续的sendResponse就无效了。原生Promise版本的优势
新版Chrome的大部分API都支持Promise写法(不需要再手动用new Promise封装回调),这样代码更简洁易读,也更容易处理错误。你的原始代码里,
responseData变量是多余的,直接在chrome.storage.local.get的回调(或Promise的then里)处理结果即可。
内容的提问来源于stack exchange,提问作者Aalok Borkar

