Reputation: 5
Content script of my extension scans some page for vendor codes and send them with chrome.runtime.sendMessage to my background script which creates new tabs and executes some code on each of them. But i faced the problem that all code runs only on the last tab.
I've tried to put it into some async/await function and it didn't work out.
chrome.runtime.onMessage.addListener(
function (request, sender, sendResponse) {
if (request.message === "open_new_tab") {
for (let vCode of request.vCodes){
chrome.tabs.create({url: "https://example.com/" + vCode}, function(){
chrome.tabs.executeScript({code: "console.log(" + vCode + ")", runAt: 'document_end'});
});
}
}
});
Upvotes: 0
Views: 748
Reputation: 73506
You didn't specify the tab id so executeScript uses the active tab. Since the API is asynchronous your executeScript is running at some unspecified time in the future when the active tab is not the tab you've created in the past.
Simply reuse the tab id provided to chrome.tabs.create's callback:
chrome.runtime.onMessage.addListener(
(request, sender, sendResponse) => {
if (request.message === 'open_new_tab') {
for (let vCode of request.vCodes) {
chrome.tabs.create({url: 'https://example.com/' + vCode}, tab => {
chrome.tabs.executeScript(tab.id, {code: `console.log(${vCode})`});
});
}
}
});
If you want to open just one tab and reuse it to load the sites sequentially, I suggest utilizing Mozilla's WebExtension polyfill and async/await:
browser.runtime.onMessage.addListener(
async (request, sender) => {
if (request.message === 'open_new_tab') {
let tab;
for (const vCode of request.vCodes) {
const url = 'https://example.com/' + vCode;
tab = tab ?
await browser.tabs.update(tab.id, {url}) :
await browser.tabs.create({url});
await browser.tabs.executeScript(tab.id, {code: `console.log(${vCode})`});
}
}
});
Upvotes: 1