Can someone help me understand the difference between the two blocks of code below? When I call await in the listener, the caller receives undefined.
chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
// (async () => {
const response = await executeScript(request);
if (response) {
console.log('Content script received message:', response);
sendResponse(response[0].result);
}
// })();
return true;
});
However, when I use the immediately-invoked async function expression, the returned value is what is returned by executeScript.
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
(async () => {
const response = await executeScript(request);
if (response) {
console.log('Content script received message:', response);
sendResponse(response[0].result);
}
})();
return true;
});
When I call await executeScript
, I am assuming that it stops the execution of the async function and suspends it until the awaited promise is resolved or rejected. How is this different from the immediately-invoked async function expression?
2
Answers
Your first code block is passing an
async
function to code that doesn’t expect to receive one. Specifically, theonMessage
code expects a function that returns either aboolean
orundefined
, but you’re passing it a function that returns a promise (because allasync
functions return promises). Since it’s not documented to handle that, that’s probably wrong. It won’t wait for the promise to settle, apparently (from your question) won’t do the right thing when it sees a value it didn’t expect, and won’t handle promise rejections.Your second code block is returning what the
onMessage
event code expects to see (true
, in your case), so that’s more likely to be right (in that regard).There’s a separate problem with the second code block though: Nothing handles promise rejection, so if an error occurs in the function, you’ll get an "unhandled rejection" warning in the console. (In some environments, it could be more significant than just a warning.) If you’re going to run an
async
function and not pass its promise on to anything, you need to be sure the function can’t throw an error and reject its promise — for instance, by wrapping everything intry
…catch
:(Or by using
.then
/.catch
instead of anasync
IIFE, but it’s nearly as verbose.)In the First Block of code, you have a created a async callback that runs as a promise and goes under pending state such that no value is returned until that promise is resolved.
In the Second Block of Code, the callback function is synchronous which initiates a async nameless-function that runs separately (independently from callback function) and returns true without waiting for the promise to be completed, sendResponse will be called as implemented in block.
To be more Precise,
Block 1 Steps:
Block 2 Steps:
i. Initiates a async Callback
ii. returns true