I am writing a chrome extension with node module "chrome-extension-async" and meeting a problem when use await
in the listener of background.
The content.js which will be injected into the page will send a message to the background, asking it to do some IO operations which is async:
// content.js
const package = await chrome.runtime.sendMessage({param: ...})
console.log(package)
// background.js
chrome.runtime.onMessage.addListener(async (request, sender,
sendResponse) => {
const value = await doIOOperation();
sendResponse(value);
})
However, chrome will report errors like below:
Uncaught (in promise) Error: The message port closed before a response was received.
I think there must be some conflict when using async/await in the listener, Anyone know how to solve this problem?
I am writing a chrome extension with node module "chrome-extension-async" and meeting a problem when use await
in the listener of background.
The content.js which will be injected into the page will send a message to the background, asking it to do some IO operations which is async:
// content.js
const package = await chrome.runtime.sendMessage({param: ...})
console.log(package)
// background.js
chrome.runtime.onMessage.addListener(async (request, sender,
sendResponse) => {
const value = await doIOOperation();
sendResponse(value);
})
However, chrome will report errors like below:
Uncaught (in promise) Error: The message port closed before a response was received.
I think there must be some conflict when using async/await in the listener, Anyone know how to solve this problem?
Share Improve this question edited Mar 18, 2022 at 2:23 pppery 3,81425 gold badges37 silver badges50 bronze badges asked Jan 3, 2019 at 6:12 Kyle HuKyle Hu 1111 gold badge1 silver badge5 bronze badges 5 |2 Answers
Reset to default 11const asyncFunctionWithAwait = async (request, sender, sendResponse) => {...}
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
asyncFunctionWithAwait(request, sender, sendResponse)
return true
})
worked for me
To expand on all the notes and clarify @RomanistHere's answer:
// a couple example async example functions
var greet;
const whatever = async function(){
greet = "hello";
}
const getSomething = async function(){
return "bob";
}
// set up a function outside the callback,
// ... giving freedom to leverage async/await.
const asyncFunctionWithAwait = async (request, sender, sendResponse) => {
// now we can do await's normally here
await whatever();
let name = await getSomething();
// since our response function is carried through "by reference",
// therefore we can call it as if it were within the listener callback.
sendResponse(greet + name)
}
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
// exec in the body of this callback,
// ... passing original function through.
asyncFunctionWithAwait(request, sender, sendResponse)
// per:
// http://developer.chrome.com/extensions/runtime.html#event-onMessage
//
// This function becomes invalid when the event listener returns,
// unless you return true from the event listener to indicate you
// wish to send a response asynchronously (this will keep the message
// channel open to the other end until sendResponse (3rd arg) is called).
return true;
});
return true
just like with the classic callback version, but the listener can't beasync
- you'll have to put the async code into IIFE or another function. I also think the WebExtension polyfill is better and BTW it correctly handles this case. – woxxom Commented Jan 3, 2019 at 7:04sendResponse
is planned to be phased out from the W3C draft. And it is to be replaced by returning a Promise. I'm assuming this is now happening on Chrome, with some users reporting that this issue is happening on Chrome 71. developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/… – tom_mai78101 Commented Jan 11, 2019 at 14:20