Связь между фоновыми скриптами и скриптом контента в цикле - PullRequest
0 голосов
/ 23 января 2019

Я разрабатываю расширение 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, а не из первого.Я думаю, что это (а) синхронная проблема, но какая?

Спасибо!

РЕДАКТИРОВАТЬ

Так что спасибо wOxxOm, который привел меня справаКстати!

Но это все еще не совсем нормально: я успешно получаю информацию по каждому URL, один за другим, и со стороны "панели", все в порядке.

Но в фоновом режиме после получения ответа со стороны содержимого для первого URL-адреса обновляется вкладка со вторым URL-адресом, но chrome.tabs.onUpdated.addListener отправляет сообщение 2 раза, один с первым URL-адресом.один со вторым, а в ответ контент отправляет в 2 раза больше своей информации.Я думаю о проблеме слушателя: может быть, мне придется удалять ее после каждого обновления?

Я не знаю, очень ли я ясен ... Вот изображение консоли:

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");
                    });
                }
            });
        });
    });
}
...