当我遇到一种非常卑鄙的行为时,我试图抓住网络工作者。出于某种原因,它会在几秒钟后终止,即使我的代码已经运行了。
这是我的代码;
主JavaScript文件:
$(document).ready(function () {
var worker = new Worker("js/TestWorker.js");
worker.addEventListener('message', function (event) {
console.log(event.data);
});
worker.addEventListener('error', function (event) {
console.log(event);
});
});
工人档案:
(function () {
var updateCounter = 0;
var updater = function () {
updateCounter += 1;
console.log("Update counter: " + updateCounter);
postMessage("test");
setTimeout(updater, 10000);
};
updater();
})();
如上所述,工人在几秒钟后停止运作,大约10-20秒左右。
但是,如果我将这段代码添加到我的主JavaScript文件中;
var check = function () {
var localWorker = worker;
// setTimeout(check, 1000);
};
// setTimeout(check, 1000);
工人按预期工作。也不需要setTimeout-calls,因此他们为什么要注释掉。 (请注意,我还可以用 worker.length 或类似的东西替换赋值,它仍然可以正常工作。
有人可以解释这种行为吗?工作人员是否被浏览器终止和(错误地)垃圾收集,或者是我在这里发生的其他事情?
值得注意的是,我的浏览器(Chrome)也没有向控制台输出任何错误或警告。
编辑:无论代码是否在匿名函数内执行,都会观察到相同的行为。
EDIT2:如果我将worker变量放在全局范围内,它不会过早终止。可能是什么原因?
答案 0 :(得分:2)
也许worker var必须是全局的
var worker;
$(document).ready(function () {
worker = new Worker("js/TestWorker.js");
worker.addEventListener('message', function (event) {
console.log(event.data);
});
worker.addEventListener('error', function (event) {
console.log(event);
});
});
答案 1 :(得分:1)
一些研究表明,虽然网络工作者应该按照您的预期运行(即不会被明显地收集垃圾),但Chrome中存在一些已知问题,这意味着您无法依赖该行为。
特别感兴趣的是这个非常类似的错误:https://bugs.chromium.org/p/chromium/issues/detail?id=572225反过来引用了一个更基础的错误:https://bugs.chromium.org/p/chromium/issues/detail?id=572226
这似乎是由于尝试垃圾收集工人,这些工人不可能执行任何未来的活动(在这种情况下,垃圾收集将无法检测到,因为它应该是),但是检测此状态的逻辑中的缺陷表示将忽略与响应传入消息无直接关系的任何待处理活动。
基本上,当你应该能够假设网络工作者表现得像DOM节点一样只能被明确删除,在实践中(现在)你需要确保你始终保持对工人可以从某个地方进入,否则当垃圾收集器踢进去时可能会杀死工人。只有在worker中使用setTimeout或类似内容时才需要这样做;如果它只是响应消息,你就不会有问题。
答案 2 :(得分:0)
(function () {
...
})();
这是一个匿名函数,在定义之后将被调用一次,之后浏览器将其抛弃。 您的网络工作者被定义为范围,这就是为什么它只能在短时间内工作。