Option #1 – Simplest
Extract to an async function.
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;
}
The return value of an async
function is implicitly wrapped in Promise.resolve
. See async doc.
The return true;
statement did the trick. It tells Chrome that you want to send a response asynchronously.
See onMessage.
Option #2 – Utility
If you feel that you will use it most frequently, create a utility, something like:
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;
})
);
Option #3 – More generic
Use mozilla/webextension-polyfill
if you prefer to “cross browsers” extension.
Example:
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"});
});