Reputation: 4871
I have an extension where I'd like to focus tabs at different times for a few seconds.
I am able to change tabs, however, I'd like to pass in a callback function for when the tab is focused.
I've tried passing in a function to sendMessage
but it appears to execute right away (seen below). How can I pass in a callback function to be executed in the content script once the tab is focused?
content_script.js
chrome.runtime.sendMessage("Do something", function(resp) {
console.log(resp)
})
background.js
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse){
chrome.windows.update(sender.tab.windowId, {"focused": true}, function(window){ });
chrome.tabs.update(sender.tab.id, {"active": true}, function(tab){
// callback function
});
});
Upvotes: 1
Views: 1377
Reputation: 73806
Return true
from onMessage listener to keep the response channel open, then call sendResponse
from a chrome API callback. Note, chrome API callbacks always run asynchronously, i.e. after the main function completes.
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
let callbackCounter = 2;
chrome.tabs.update(sender.tab.id, {active: true}, function (tab) {
// this callback runs after the parent function has finished
if (--callbackCounter === 0) {
sendResponse({foo: 'bar'});
}
});
chrome.windows.update(sender.tab.windowId, {focused: true}, function (window) {
// this callback runs after the parent function has finished
if (--callbackCounter === 0) {
sendResponse({foo: 'bar'});
}
});
// keep the response channel open
return true;
});
In modern browsers this is solved usually with Promise API.
You can use it with Chrome API by loading Mozilla WebExtension polyfill.
browser.runtime.onMessage.addListener((request, sender) => {
return Promise.all([
browser.tabs.update(sender.tab.id, {active: true}),
browser.windows.update(sender.tab.windowId, {focused: true}),
]).then(() => {
// .........
return {foo: 'bar'};
});
});
The polyfill also enables you to use await/async syntax:
browser.runtime.onMessage.addListener(async (request, sender) => {
await Promise.all([
browser.tabs.update(sender.tab.id, {active: true}),
browser.windows.update(sender.tab.windowId, {focused: true}),
]);
return {foo: 'bar'};
});
Upvotes: 3