【问题标题】:Console.log double logging from web workers来自网络工作者的 Console.log 双重日志记录
【发布时间】:2018-02-28 20:37:58
【问题描述】:

我的意图是在创建后将一条消息传递给工作人员,并让工作人员记录该消息并发送回复。发生的情况是发送给 web worker 的消息被记录了两次,并且只发送了一个回复。如果您使用开发人员工具刷新页面或暂停执行,则该消息会正确记录一次。

我创建了一个微型扩展来演示这一点。有一个后台脚本监听点击浏览器操作按钮。单击它时,会打开一个新选项卡,该选项卡会生成 2 个 Web Worker。这些工作人员侦听消息并记录它们,并发送回复说明已收到消息。然后新打开的选项卡发送消息,并记录回复。

Google drive with all of the files needed to run this as a chrome extension

Image demonstrating the double logging of the message

一些参考资料:

我已经在我的扩展上工作了一段时间,并且遇到了各种有趣的错误,尤其是异步代码。最后,我总是能够自己调试它们或找到解释问题的参考。感谢您提供的任何帮助!

background.js

const tabUrl = chrome.extension.getURL("tab.html");

function browserActionCallback(tab) {

    function createResultsTab() {

        chrome.tabs.create({
            "url": tabUrl,
            "index": tab.index + 1
        }, function() {
            console.log("Tab created");         
        });
    }

    (function tabHandler() {
        chrome.tabs.query({"url":tabUrl}, (tabQueryResults) => {
            if (tabQueryResults.length > 0) {
                chrome.tabs.remove(tabQueryResults[0].id, () => {
                    createResultsTab();
                });
            } else {
                createResultsTab();
            }
        });
    })();
}

chrome.browserAction.onClicked.addListener((tab) => {
    browserActionCallback(tab);
});

tab.js

function createWorkers(num) {
    /*in original extension I intended to let the user change number of workers in options*/

    var workers = new Array(num);
    for (let i = 0; i < num; i++) {
        workers[i] = new Worker("worker.js");
    }
    return workers;
}

function messageWorkers(workers) {
    let len = workers.length
    for (let i = 0; i < len; i++) {
        let message = "Connection " + i + " started";
        workers[i].postMessage(message);
        workers[i].onmessage = function(e) {
            console.log(e.data);            
        }
    }   
}

var numWorkers = 2;
const WORKERS = createWorkers(numWorkers);
console.log("Before");
messageWorkers(WORKERS);
console.log("After");

worker.js

onmessage = function(msg) {
    console.log(msg.data);
    postMessage("Worker reply- " + msg.data);
}

编辑 1:更改 tab.js messageWorkers 函数的 for 循环,以便在 postMessage 之前设置 onmessage 不会更改结果。发送多条消息也不会改变结果。如果我在工作人员的 onmessage 函数开始时有一个 console.log 语句,它记录了该函数已经开始,它也会记录两次。重申一下,这仅在后台脚本创建此选项卡时发生,而不是在刷新页面或使用调试器时发生。

编辑 2:在 devtools 控制台中,有一个下拉菜单可以在 top 和 workers 之间进行选择。选中“仅选定上下文”选项会使重复的日志记录消失,但是这个视图比我想要的要窄一些

【问题讨论】:

    标签: javascript google-chrome web-worker console.log browser-extension


    【解决方案1】:

    我可以确认这个问题。重现它的示例代码:

    index.js

    function worker() {
      console.log('this logged twice');
    }
    
    const workerBlob = new Blob(
      [worker.toString().match(/function[^{]+\{([\s\S]*)\}$/)[1]],
      {type: 'text/javascript'}
    );
    const workerBlobUrl = URL.createObjectURL(workerBlob);
    
    new Worker(workerBlobUrl);
    

    使用 index.js 作为 Chrome 扩展程序后台脚本,在加载扩展程序或重新启动 Chrome 时,"this logged twice" 将被记录两次。

    【讨论】:

      猜你喜欢
      • 2012-12-19
      • 2014-03-21
      • 1970-01-01
      • 1970-01-01
      • 2018-01-24
      • 2011-11-12
      • 2012-02-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多