关于Web Workers并行性

3

我的主线程的JS代码:

$('body').on('click',function(){alert('click');});
var worker = new Worker('worker.js');
worker.addEventListener('message', function(e) {    
        console.log(e.data);
});

以及 worker.js 内的代码。

var n = 1;
while (true) {
  n++;
  postMessage(n);
}

我刚开始学习有关于Web workers的知识。它们不会阻塞用户界面,可以让您与之交互,并在单独的线程中运行以实现并行性。但实际上,运行上述代码时得到的结果是浏览器卡住了,无法响应任何点击。虽然工作线程输出数字,但用户界面依旧被阻塞了。我希望能够得到一些好的解释。谢谢!

Web Workers与主线程没有共享内存,因此每次在它们之间传递数据时,线程都必须暂停,直到接收方响应。 - Derek 朕會功夫
2个回答

3

在Web Worker内部完成的工作不会阻塞主线程中的任何内容。

向主线程发送消息需要主线程接收并处理该消息,这确实会占用主线程。

一个类比:

为了进行更重要的事情,Alice已经请Bob为她数到1000。

如果Bob只是默默地数到1000,那么一切都很好。

不幸的是,她要求他每次数到一个新数字时告诉她。

"Alice!Alice!Alice!"

"怎么了,Bob?"

"1!"

"Alice!Alice!Alice!"

"怎么了,Bob?"

"2!"

(注:实际上,这将是异步的:Bob将继续计数,并将一个越来越长的数字队列推向Alice,Alice必须读取消息并查看数字)

Web Workers用于长时间运行的操作。您的操作不是长时间运行的,每次执行非常短的循环时,它需要与主线程通信。


2
您正在通过postMessage()从worker发送消息,导致主线程被淹没。它们可能比分派和记录它们的速度更快,因此没有其他时间供主线程做其他事情。更改您的postMessage调用,只有在500ms经过后才向主线程发送更新,这样您就不会过载主线程,使其能够在消息之间执行其他操作。
例如,在worker.js中尝试以下内容:
var n = 1;
var lastSend = Date.now();
var now;
while (true) {
  n++;
  now = Date.now();
  if (now - lastSend > 500) {
      lastSend = now;
      postMessage(n);
  }
}

而且,每500毫秒只会发送最新计数的postMessage,以避免主线程尝试处理所有这些消息而导致过载。

为了使Worker独立于主线程运行,它需要实际上独立于主线程,执行独立的工作,而不是一直尝试与其通信。 它最适用于大部分与主线程无关并且仅偶尔需要与主线程通信的计算密集型操作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接