I'm creating a browser extension where I need to capture a full-page screenshot. The process involves sending message signals between popup and background script and content-script. However, the await in the popup isn't waiting for the background script to complete its operation. After calling the message signal it immediately jumps to below code execution.
// Popup (App.tsx)
if (capturetype === 'fullpage'): {
console.log('Capturing full page...');
const url = await browser.runtime.sendMessage({
type: "CAPTURE_FULL_PAGE",
tab,
})
console.log("above function executed, result ->", url) // Executes immediately, url is undefined
}
// Background script
browser.runtime.onMessage.addListener(async (message: any, _sender: any) => {
if (message.type === "CAPTURE_FULL_PAGE") {
// Long running operation
const dimensions = await browser.tabs.sendMessage(tab.id, {
type: "GET_FULL_PAGE_DIMENSIONS"
}); // sends message to content-script
// More async operations, didnt add for now.
return { success: true, dataUrl: finalImage };
}
});
// Content Script
browser.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.type === "GET_FULL_PAGE_DIMENSIONS") {
sendResponse({
width: Math.max(document.documentElement.scrollWidth, document.body.scrollWidth),
height: Math.max(document.documentElement.scrollHeight, document.body.scrollHeight),
viewportHeight: window.innerHeight,
originalScroll: window.scrollY
});
}
});
CONSOLE LOG:
full page...
above function executed, result -> undefined
// Later, background operations complete but popup already moved on
I have tried the followings:
- Adding
awaitto the message sending - Using
Promise.all - Wrapping the response in
Promise.resolve()
Why isn't the await waiting for the background script to complete, and how can I properly handle this async communication between popup and background script?
NOTE: The extension is created using WXT framework
asyncto the function. Prependingasyncchanges the meaning to sending an asynchronous response using a promise, which is effectively the same assendResponse(true)."content_scriptsafter reloading/installing the extension in Chrome.