【问题标题】:Posting a message to a web worker while it is still running在 Web Worker 仍在运行时向其发布消息
【发布时间】:2017-11-17 20:07:11
【问题描述】:

假设我们有一个 web worker 引用一个名为“worker.js”的文件。我们使用 worker 执行“worker.js”中的一个函数,该函数执行一些冗长的操作。我们调用 post 将相应的消息发送给 worker 并在主线程中继续。但是,在 worker 完成初始工作之前,主线程会向它发送另一条消息。

我的问题:worker 会继续我们的计时功能,只在完成后处理新发布的消息,还是会中断当前操作直到新消息完成?

【问题讨论】:

标签: javascript multithreading asynchronous interrupt web-worker


【解决方案1】:

我在谷歌浏览器的调试器中试用了以下代码:

worker.js:

var cosine;
self.onmessage = function(e) {
    if (e.data.message == 0) {
        for (var i = 0; i < 10000000; i++) {
            cosine = Math.cos(Math.random());
            if (i % 1000 == 0) console.log("hello world");
        }
    } else if (e.data.message == 1) {
        console.log("xyz");
    }
};

main.js:

var worker;

function main() {
    worker = new Worker("js/worker.js");
    worker.postMessage({message: 0});
    setTimeout(xyz, 10);
}

function xyz() {
    worker.postMessage({message: 1});
}

输出:

(10000 times) test.js:11 hello world
test.js:14 xyz

每次新迭代都会重新计算余弦变量,以提供问题中描述的“耗时”算法。 显然,只有在最后一个操作完成后才会收到消息,因为我观察到在第 10000 个“hello world”输出之后立即打印“xyz”输出。

【讨论】:

  • 谢谢!它有很大帮助。这对工人来说是非常有帮助的稳定行为。
【解决方案2】:

Web Worker 由单个线程支持。这意味着当“onmessage”处理程序正在执行时,它将无法接收另一个“onmessage”事件,直到前一个事件完成。

如果我们想实现一些我们希望能够暂停和恢复的后台计算过程,这非常不方便,因为没有办法向正在运行的工作人员发送“暂停”消息。我们可以通过 worker.terminate() 停止一个 web worker,但这完全杀死了这个 worker。

我能想到的唯一方法是将worker执行切成块,然后在每个块的末尾发布一条消息来自worker,然后触发一条消息 处理下一个块的worker,以此类推。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-14
    • 2019-01-22
    • 2021-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 2013-01-02
    相关资源
    最近更新 更多