带有异步等待的 chrome.runtime.onMessage 响应

新手上路,请多包涵

我想在 onMessage 侦听器中使用异步等待:

 chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) =>{
    var key = await getKey();
    sendResponse(key);
});

但是,当我发送消息时,我得到了 undefined 。

来自 chrome.runtime.onMessage.addListener 的文档:

当事件侦听器返回时,此函数将失效,除非您从事件侦听器返回 true 以指示您希望异步发送响应(这将使消息通道向另一端保持打开状态,直到调用 sendResponse)。

这在我使用回调时有效。

 chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) =>{
    getKey(key => {
        sendResponse(key);
    });
    return true;
});

但是我想利用 await 语法。但它似乎不起作用并且仍然返回未定义:

 chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) =>{
    var key = await getKey();
    sendResponse(key);
    return true;
});

原文由 Chris 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 3.2k
1 个回答

选项 #1 - 最简单

提取到异步函数。

 chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  doSomethingWith(request).then(sendResponse);
  return true; // return true to indicate you want to send a response asynchronously
});

async function doSomethingWith(request) {
  var key = await getKey();
  // await .....
  return key;
}

async 函数的返回值隐式包装在 Promise.resolve 中。请参阅 异步文档

return true; 语句起到了作用。它告诉 Chrome 您想要异步发送响应。

请参阅 消息

选项 #2 - 实用程序

如果您觉得您会最频繁地使用它,请创建一个实用程序,例如:

 const wrapAsyncFunction = (listener) => (request, sender, sendResponse) => {
  // the listener(...) might return a non-promise result (not an async function), so we wrap it with Promise.resolve()
  Promise.resolve(listener(request, sender)).then(sendResponse);
  return true; // return true to indicate you want to send a response asynchronously
};

chrome.runtime.onMessage.addListener(
  wrapAsyncFunction(async (request, sender) => {
    console.log(request, sender);

    const key = await getKey();
    // await .....
    return key;
  })
);

选项 #3 - 更通用

如果您更喜欢“跨浏览器”扩展,请使用 mozilla/webextension-polyfill

例子:

 var browser = require("webextension-polyfill");

browser.runtime.onMessage.addListener(async (msg, sender) => {
  console.log("BG page received message", msg, "from", sender);
  console.log("Stored data", await browser.storage.local.get());
});

browser.browserAction.onClicked.addListener(() => {
  browser.tabs.executeScript({file: "content.js"});
});

原文由 Ninh Pham 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题