后台脚本和内容脚本之间的循环通信

时间:2019-01-23 09:15:22

标签: javascript google-chrome-extension promise synchronous sendmessage

我正在开发一个chrome扩展程序:

  • 打开带有按钮的“面板”
  • 单击按钮时,将创建一个新标签页
  • 然后在这个新选项卡中,我遍历URL数组以检索每个URL上的信息

对于这些操作,我正在使用Promises,因为我认为这是这样做的方法:)

background.js

chrome.browserAction.onClicked.addListener(function (tab) {
    var tabUrl = tab.url;
    originalWindowId = tab.windowId;
    var popupURL = chrome.runtime.getURL("extension/main_panel.html");
    chrome.windows.create({
        url: popupURL,
        type: 'panel',
        width: 600,
        height: 520
    }, function (window) {
        extensionWindowId = window.id;
    });
});

function createNewTab() {
    return new Promise(function (resolve, reject) {
        chrome.tabs.create({
            url: "about:blank"
        }, function (tab) {
            console.log("tab created with id " + tab.id);
            resolve(tab.id);
        });
    });
}

function updateNewTab(newTabId, url) {
    return new Promise(function (resolve, reject) {
        chrome.tabs.update(newTabId, {
            url: url
        }, function (tab) {
            console.log("tab with id " + tab.id + " updated");
            chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
                if (changeInfo.status === 'complete') {
                    console.log("tab with id " + tab.id + " and url " + url + " updated complete");
                    chrome.tabs.sendMessage(tab.id, {
                        action: "getATitle"
                    }, function (response) {
                        if (response.data != "") {
                            resolve(response.data);
                        } else
                            reject("failed");
                    });
                }
            });
        });
    });
}

main_panel.js

var urls = ["https://forum.openstreetmap.fr/viewtopic.php?f=3&t=6811&start=0", "https://forum.openstreetmap.fr/viewtopic.php?f=3&t=6811&start=25"];
const j = urls.length;

var background = chrome.extension.getBackgroundPage();

var scrapButton = document.getElementById("scrap_button");
scrapButton.addEventListener("click", function () {
    background.
    createNewTab()
        .then(function (newTabId) {
            console.log("response : newTabId " + newTabId);
            var all = []; 
            for (let i = 0; i < j; i ++) {
                console.log("try with i = " + i + " | url = " + urls[i]);
                var p = background.updateNewTab(newTabId, urls[i]);
                all.push(p);
            }
            return Promise.all(all);
        })
        .then(function (values) {
            console.log(values);
        })

});

content.js

chrome.runtime.onMessage.addListener(
    function (request, sender, sendResponse) {
        console.log("request from bg : " + request.action + " | url = " + location.href);
        if (request.action == "getATitle") {
            var title = $("h3.first a").text();
            console.log("title = " + title);
            sendResponse({
                data: title
            });
        }
    }
);

所以我的问题是我从第二个URL而不是从第一个URL检索到两倍的结果。我认为这是一个(a)同步问题,但有一个?

谢谢!

编辑

感谢wOxxOm的正确驾驶!!

但这还不是完全可以的:我成功地检索了每个URL的信息,一个接一个,并且从“面板”侧,一切都很好。

但是在后台,当它收到来自内容方的第一个URL的响应后,会使用第二个URL更新选项卡,但是chrome.tabs.onUpdated.addListener发送消息两次,一次是使用第一个URL,一次是第二,作为响应,内容发送的信息是其信息的两倍。 我想到了一个监听器问题:也许我必须在每次更新后将其删除?

我不知道我是否很清楚……这是控制台的图片:

console log of background.js

这是main_panel.js的新代码

var background = chrome.extension.getBackgroundPage();

var scrapButton = document.getElementById("scrap_button");
scrapButton.addEventListener("click", function () {
    background.
    createNewTab()
        .then(function (newTabId) {
            console.log("response : newTabId " + newTabId);
            return processUrls(newTabId);
        })
});

async function delayedUpdate(newTabId, url, response) {
    const data = await background.updateNewTab(newTabId, url);
    console.log("data : " + data);
}

async function processUrls(newTabId) {
    for (const url of urls) {
        console.log("try with url = " + url);
        await delayedUpdate(newTabId, url);
    }
    console.log('Done!');
}

编辑2

感谢wOxxOm帮助我完成了background.js的最终代码:

function updateNewTab(newTabId, url) {
    return new Promise(function (resolve, reject) {
        chrome.tabs.update(newTabId, {
            url: url
        }, function (tab) {
            console.log("tab with id " + tab.id + " updated");
            chrome.tabs.onUpdated.addListener(function tabUpdatedListener(tabId, changeInfo, tab) {
                if (changeInfo.status === 'complete') {
                    console.log("tab with id " + tab.id + " and url " + url + " updated complete");
                    chrome.tabs.sendMessage(tab.id, {
                        action: "getATitle"
                    }, function (response) {
                        console.log("data received in bg : " + response.data);
                        if (response.data != "") {
                            resolve(response.data);
                 chrome.tabs.onUpdated.removeListener(tabUpdatedListener);
                        } else
                            reject("failed");
                    });
                }
            });
        });
    });
}

0 个答案:

没有答案