繁体   English   中英

反应Chrome扩展和承诺

[英]React Chrome extension and Promises

我在ReactJS中编写Chrome扩展程序。

我正在遍历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:

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

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

我的问题是response.content似乎总是相同的。 更重要的是,更新的标签似乎只显示了数组中的最后一个URL。 我认为我处理Promises的方式存在问题。

任何帮助表示赞赏。

您的代码的问题在于,在继续下一个URL之前,它不会等待上一个URL加载,因此只有最后一个URL才实际加载到选项卡中。

我建议使用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;
}

async函数内调用:

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

PS,您还可以在后台的新窗口中一次打开所有URL,假设不会出现10个以上的URL,否则您将冒用尽用户RAM的风险。

暂无
暂无

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

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