简体   繁体   English

反应Chrome扩展和承诺

[英]React Chrome extension and Promises

I am writing a Chrome extension in ReactJS. 我在ReactJS中编写Chrome扩展程序。

I am looping through an array of URLs and trying to get the the HTML content of those pages. 我正在遍历URL数组并尝试获取这些页面的HTML内容。

this.state.advertData.map(function(e, i) {

    common.updateTabUrl(e.url).then((tab) => {

        common.requestHTML(tab).then((response) => {

            console.log(response.content);

        })

    });

})

common.js: common.js:

let requestHTML = function(tab) {

    return new Promise(function(resolve, reject) {

        chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
            chrome.tabs.sendMessage(tab.id, {'req': 'source-code'}, function (response) {

                resolve(response)

            })
        })

    })

}

let updateTabUrl = function(url) {

    return new Promise(function(resolve, reject) {

        let update = chrome.tabs.update({
            url: url
        }, function(tab) {
            chrome.tabs.onUpdated.addListener(function listener (tabId, info) {
                if (info.status === 'complete' && tabId === tab.id) {
                    chrome.tabs.onUpdated.removeListener(listener);
                    resolve(tab);
                }
            });


        })

    })
}

content_script.js content_script.js

chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
    let response = '';
    if (request.req === 'source-code') {
        response = document.documentElement.innerHTML;
    }
    sendResponse({content: response});
});

My issue is that the response.content always seems to be the same. 我的问题是response.content似乎总是相同的。 More importantly, the tab that updates seems to only ever display the last url in my array. 更重要的是,更新的标签似乎只显示了数组中的最后一个URL。 I think it is a problem with the way I am handling Promises. 我认为我处理Promises的方式存在问题。

Any help is appreciated. 任何帮助表示赞赏。

The problem with your code is that it doesn't wait for the previous URL to load before proceeding to the next one so only the last one gets actually loaded in a tab. 您的代码的问题在于,在继续下一个URL之前,它不会等待上一个URL加载,因此只有最后一个URL才实际加载到选项卡中。

I suggest using 1) Mozilla's WebExtension polyfill , 2) await/async syntax, 3) executeScript that automatically runs when a tab is complete by default 4) a literal code string in executeScript so you don't need neither a separate file nor to declare the content script in manifest.json. 我建议使用1) Mozilla的WebExtension polyfill ,2)等待/异步语​​法,3)默认情况下在选项卡完成时自动运行的executeScript 4) executeScript中的文字代码字符串,因此您既不需要单独的文件也无需声明manifest.json中的内容脚本。

async function getUrlSourceForArray({urls, tabId = null}) {
  const results = [];
  for (const url of urls) {
    await browser.tabs.update(tabId, {url});
    const [html] = await browser.tabs.executeScript(tabId, {
      code: 'document.documentElement.innerHTML',
    });
    results.push(html);
  }
  return results;
}

Invoking inside an async function: async函数内调用:

const allHtmls = await getUrlSourceForArray({
  urls: this.state.advertData.map(d => d.url),
  tabId: null, // active tab
});

PS you can also open all the URLs at once in a new window in background, assuming there won't be more than say 10 URLs, otherwise you would risk exhausting the user's RAM. PS,您还可以在后台的新窗口中一次打开所有URL,假设不会出现10个以上的URL,否则您将冒用尽用户RAM的风险。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM