我想在onMessage侦听器中使用异步等待:
chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) =>{
var key = await getKey();
sendResponse(key);
});
但是,当我发送消息时,我会感到不确定。
来自chrome.runtime.onMessage.addListener的文档:
当事件侦听器返回时,此函数将变得无效,除非您从事件侦听器返回true以指示您希望异步发送响应(这将使消息通道一直打开到另一端,直到调用sendResponse )。
当我使用回调时,这是可行的。
chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) =>{
getKey(key => {
sendResponse(key);
});
return true;
});
然而,我想利用等待语法。但是,它似乎不起作用,并且仍然返回未定义的:
chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) =>{
var key = await getKey();
sendResponse(key);
return true;
});
发布于 2017-10-08 06:24:14
选项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"});
});
发布于 2019-07-22 08:21:39
不确定Chrome扩展运行时环境是否支持异步/等待语法,但您可以使用转换程序(即Babel)将其转换为例如ES5。然后,您可以定义如下包装器函数:
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;
}
然后,您可以像这样使用:
chrome.runtime.onMessage.addListener(asChromeListener(async (message, sender) => {
return await doMyAsyncWork(message);
});
由于我们使用的是TypeScript,这里还有我们实际使用的片段(泛型类型)。
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;
}
发布于 2021-08-13 00:36:48
函数在有响应时调用(最多一次)。参数应该是任何JSON可见的对象。如果同一文档中有多个onMessage侦听器,则只能发送一个响应。当事件侦听器返回时,此函数将变得无效,除非从事件侦听器返回真正的,以指示您希望异步发送响应(这将使消息通道保持打开状态,直到调用sendResponse )。
https://developer.chrome.com/docs/extensions/reference/runtime/#event-onMessage
不得不说官方的医生真的很难读懂。
https://stackoverflow.com/questions/44056271
复制相似问题