2016-12-13 35 views
3

所以我一直在和一位同事讨论JavaScript事件循环和Web Workers的使用。在一个单一的Web页时,不同的Web工人具有不同的堆栈,堆,和消息队列,形式here,具体有:JavaScript事件循环和Web Workers

A web worker or a cross-origin iframe has its own stack, heap, and message 
queue. Two distinct runtimes can only communicate through sending messages via 
the postMessage method. This method adds a message to the other runtime if the 
latter listens to message events. 

但都是相同的事件循环内执行的消息,或确实每个Web工人具有其自己的事件循环?

我在问这个,因为我在一个页面中有两个Web Workers,一个按顺序执行一个非常计算繁重的操作,而另一个只处理WebRTC连接。 我不会详细讨论,但在我看来,计算量巨大的Web Worker正在从JavaScript事件循环中消除太多的计算时间,以至于其他Worker只需要保持连接活着(通过我想的心跳)无法这样做,连接最终会丢失。

这是我相信的。如果情况并非如此,并且两个Web Workers在不同的事件循环上工作,那么当计算Web Worker上的负载很重(负载轻时连接不会丢失)时,我无法解释为什么连接丢失。

回答

3

每个工人都有自己的事件循环。从the specification

每个WorkerGlobalScope对象具有不同的事件循环,从那些由相关类似来源的浏览上下文单元中使用分开的。

然后here

在全球范围内是工人的 “内部”。

...后面跟着前面引用中引用的接口WorkerGlobalScope的定义。

您的计算繁重的工作人员可能会支配可用的处理时间,但它不会阻塞其他工作人员的事件循环。

我们也可以很容易地以快速测试检查:

page.html

<!DOCTYPE HTML "http://www.w3.org/TR/html4/strict.dtd"> 
<html> 
<head> 
<meta charset="UTF-8"> 
<title>Two Workers</title> 
<style> 
body { 
    font-family: sans-serif; 
} 
pre { 
    margin: 0; 
    padding: 0; 
} 
</style> 
</head> 
<body> 
<div>Fast: <span id="fast"></span></div> 
<div>Slow: <span id="slow"></span></div> 
<script> 
(function() { 
    var fastWorker = new Worker("fastworker.js"); 
    var fast = document.getElementById("fast"); 
    var slowWorker = new Worker("slowworker.js"); 
    var slow = document.getElementById("slow"); 

    fastWorker.addEventListener("message", function(e) { 
     fast.innerHTML = e.data || "??"; 
     fastWorker.postMessage("ping"); 
    }); 

    slowWorker.addEventListener("message", function(e) { 
     slow.innerHTML = e.data || "??"; 
     slowWorker.postMessage("ping"); 
    }); 

    fastWorker.postMessage("start"); 
    slowWorker.postMessage("start"); 
})(); 
</script> 
</body> 
</html> 

slowworker.js

var counter = 0; 
self.addEventListener("message", function(e) { 
    var done = Date.now() + 1000; // 1 second 
    while (Date.now() < done) { 
     // Busy wait (boo!) 
    } 
    ++counter; 
    self.postMessage(counter); 
}); 

fastworker.js

var counter = 0; 
self.addEventListener("message", function(e) { 
    var done = Date.now() + 100; // 100ms 
    while (Date.now() < done) { 
     // Busy wait (boo!) 
    } 
    ++counter; 
    self.postMessage(counter); 
}); 

正如你所看到的,“快”的数字比“慢”的数字快得多,表明它正在处理它的消息。

(我可以做出一个工作文件,并在发出启动命令的延迟,但是......)

+1

我想到了工人独霸* *机器的可用的处理时间,但它听起来有点很遥远,我不认为这会发生。无论如何,谢谢你的回复和代码! :)我会尝试找到解决方法,以缓慢的工人问题。 – Masiar