考虑以下来自以下网站的Webworker代码:https://www.html5rocks.com/en/tutorials/workers/basics/
网页:
<button onclick="sayHI()">Say HI</button>
<button onclick="unknownCmd()">Send unknown command</button>
<button onclick="stop()">Stop worker</button>
<output id="result"></output>
<script>
function sayHI() {
worker.postMessage({'cmd': 'start', 'msg': 'Hi'});
}
function stop() {
// worker.terminate() from this script would also stop the worker.
worker.postMessage({'cmd': 'stop', 'msg': 'Bye'});
}
function unknownCmd() {
worker.postMessage({'cmd': 'foobard', 'msg': '???'});
}
var worker = new Worker('doWork2.js');
worker.addEventListener('message', function(e) {
document.getElementById('result').textContent = e.data;
}, false);
</script>
然后在doWork2.js中:
self.addEventListener('message', function(e) {
var data = e.data;
switch (data.cmd) {
case 'start':
self.postMessage('WORKER STARTED: ' + data.msg);
break;
case 'stop':
self.postMessage('WORKER STOPPED: ' + data.msg +
'. (buttons will no longer work)');
self.close(); // Terminates the worker.
break;
default:
self.postMessage('Unknown command: ' + data.msg);
};
}, false);
因此,当您单击SayHi时,doWork2中定义的“消息”事件处理程序将首先接收该事件。然后,它将触发另一个“消息”事件,该事件由打印出消息的主页上定义的处理程序接收。
步骤流就是这样。
请回答以下两个问题:
问题1::在上面的步骤2中,为什么触发了doWork2中的处理程序,但未触发页面上的处理程序?
问题2:在从doWork2触发事件后的第4步中,为什么页面上的处理程序被执行,但是doWork2中的处理程序没有递归执行?
答案 0 :(得分:0)
之前触发doWorks2事件侦听器的原因是因为javascript解释代码的方式。 Java语言中的代码执行是在两个方向都有异步功能的情况下发生的。有一个调用堆栈,其中的命令以同步顺序或经典顺序运行,然后对于异步功能,有一个消息队列,该消息队列按事件的添加顺序将事件排队。
查看更多:https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop
答案 1 :(得分:0)
事实证明,在两个不同的对象上有两种postMessage实现。
问题1的答案
在调用worker.postMessage()时
...工作程序接口向工作程序的内部范围发送一条消息
因此页面上的消息事件处理程序看不到它。
问题2的答案
调用self.postMesssage时,self
是工作程序的全局范围,其实现方式如下:
使用以下命令将信息发送回产生该信息的线程
DedicatedWorkerGlobalScope.postMessage
方法。
因此,它不会递归调用自身,因为消息事件仅在产生它的线程中可见。
来源:https://developer.mozilla.org/en-US/docs/Web/API/Worker/postMessage