I want to use async await in an onMessage listener:
chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) =>{
var key = await getKey(
Not sure if Chrome extension runtime environment supports the async/await syntax, but you can use a transpiler (i.e. Babel) to have it converted to for example ES5. Then you can define a wrapper function like this:
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;
}
Which you can then use like:
chrome.runtime.onMessage.addListener(asChromeListener(async (message, sender) => {
return await doMyAsyncWork(message);
});
Since we use TypeScript, here's also the snippet that we actually use (with generic types).
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;
}
Honestly, it looks like Google Chrome Extensions don't support the await
keyword. I've successfully used asynchronous chrome.runtime.onMessage.addListener
's before, and every time I try to use await
I see this syntax error in the Chrome Debugging Tools, on the line that I use await
:
Here's how I've been testing:
I created a very basic listener:
chrome.runtime.onMessage.addListener(function(data, MessageSender, sendResponse) {
sendResponse(awaitTester);
var async = true;
// returns true if asyncronous is needed
if (async) return true;
});
my awaitTester
function looks like this:
function awaitTester() {
var prom = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve('test');
}, 4000);
});
var awaited = await prom;
return awaited;
}
finally, my message sender is what you'd expect:
chrome.runtime.sendMessage({}, function(message) {
debugger;
console.log(message);
});
And in the debugger / console I always get undefined
.
I do work-around by extracting 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.
See onMessage.
you could try this
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
new Promise(async send => {
var key = await getKey();
send(key);
}).then(sendResponse)
return true;
});