首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >异步等待的chrome.runtime.onMessage响应

异步等待的chrome.runtime.onMessage响应
EN

Stack Overflow用户
提问于 2017-05-18 19:25:11
回答 7查看 18.1K关注 0票数 45

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

代码语言:javascript
运行
复制
chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) =>{
    var key = await getKey();
    sendResponse(key);
});

但是,当我发送消息时,我会感到不确定。

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

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

当我使用回调时,这是可行的。

代码语言:javascript
运行
复制
chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) =>{
    getKey(key => {
        sendResponse(key);
    });
    return true;
});

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

代码语言:javascript
运行
复制
chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) =>{
    var key = await getKey();
    sendResponse(key);
    return true;
});
EN

回答 7

Stack Overflow用户

发布于 2017-10-08 06:24:14

选项1-最简单

提取到异步函数。

代码语言:javascript
运行
复制
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您希望异步发送响应。

onMessage

选项2-实用程序

如果您认为您将最频繁地使用它,请创建一个实用程序,如下所示:

代码语言:javascript
运行
复制
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

示例:

代码语言:javascript
运行
复制
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"});
});
票数 67
EN

Stack Overflow用户

发布于 2019-07-22 08:21:39

不确定Chrome扩展运行时环境是否支持异步/等待语法,但您可以使用转换程序(即Babel)将其转换为例如ES5。然后,您可以定义如下包装器函数:

代码语言:javascript
运行
复制
function asChromeListener(listener) {
  return (message, sender, sendResponse) => {
    const returnValue = listener(message, sender);

    if (isPromise(returnValue)) {
      returnValue.then(sendResponse);
      return true;
    }
    else {
      if (typeof returnValue !== 'undefined') {
        sendResponse(returnValue);
      }
      return false;
    }
  };
}

function isPromise(value) {
  return typeof value === 'object' && value !== null && 'then' in value && 'catch' in value;
}

然后,您可以像这样使用:

代码语言:javascript
运行
复制
chrome.runtime.onMessage.addListener(asChromeListener(async (message, sender) => {
  return await doMyAsyncWork(message);
});

由于我们使用的是TypeScript,这里还有我们实际使用的片段(泛型类型)。

代码语言:javascript
运行
复制
export function asChromeListener<M, S, R extends Function>(listener: (message: M, sender: S) => any) {
  return (message: M, sender: S, sendResponse: R) => {
    const returnValue = listener(message, sender);

    if (isPromise(returnValue)) {
      returnValue.then(sendResponse);
      return true;
    }
    else {
      if (typeof returnValue !== 'undefined') {
        sendResponse(returnValue);
      }
      return false;
    }
  };
}

function isPromise(value: any) {
  return typeof value === 'object' && value !== null && 'then' in value && 'catch' in value;
}
票数 4
EN

Stack Overflow用户

发布于 2021-08-13 00:36:48

函数在有响应时调用(最多一次)。参数应该是任何JSON可见的对象。如果同一文档中有多个onMessage侦听器,则只能发送一个响应。当事件侦听器返回时,此函数将变得无效,除非从事件侦听器返回真正的,以指示您希望异步发送响应(这将使消息通道保持打开状态,直到调用sendResponse )。

https://developer.chrome.com/docs/extensions/reference/runtime/#event-onMessage

不得不说官方的医生真的很难读懂。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44056271

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档