为什么调用已终止的工作人员的 postMessage 不会抛出一些错误?
Why does postMessage called upon terminated worker not throw some error?
web worker终止后,为什么我调用它postMessage
不报错?
是否可以在没有构造函数的情况下使用现有的已终止实例重新启动 worker new Worker("same-worker.js")
?
const myWorker = new Worker("my-worker.js");
myWorker.addEventListener("message", function(event) {
const message = event.data;
console.log("from worker", message);
myWorker.terminate();
myWorker.postMessage("");
// what happens here, is only silence
// Why not throw error?
});
myWorker.postMessage(""); //start it, maybe receive a response
编辑:我问的是这种特殊设计的基本原理。 XHR、WebSocket 和 WebRTC 在尝试对已终止的实例执行操作时会立即抛出异常。
根据文档,工人的 terminate 方法
immediately terminates the Worker. This does not offer the worker an opportunity to finish its operations; it is simply stopped at once.
我认为,由于实例即使处于这种死状态,它仍然存在,因此执行 postMessage
不会抛出,但由于您的工作人员未处理任何操作,它只会什么都不做。
据我所知,无法恢复工作人员,但如果您希望能够随意恢复它,您也可以通过消息设置一个布尔值来暂停您的处理。
tl;dr jsFiddle
我无法回答为什么,因为我不是编写javascript标准的人。但是没有任何迹象表明工人是否已经终止。
正在检测终止
如果您需要检测此状态,则必须创建您自己的 API。我建议将这个基于简单函数的草稿作为起点:
//Override worker methods to detect termination
function makeWorkerSmart(workerURL) {
// make normal worker
var worker = new Worker(workerURL);
// assume that it's running from the start
worker.terminated = false;
// allows the worker to terminate itself
worker.addEventListener("message", function(e) {
if(e.data == "SECRET_WORKER_TERMINATE_MESSAGE") {
this.terminated = true;
console.info("Worker killed itself.");
}
});
// Throws error if terminated is true
worker.postMessage = function() {
if(this.terminated)
throw new Error("Tried to use postMessage on worker that is terminated.");
// normal post message
return Worker.prototype.postMessage.apply(this, arguments);
}
// sets terminate to true
// throws error if called multiple times
worker.terminate = function() {
if(this.terminated)
throw new Error("Tried to terminate terminated worker.");
this.terminated = true;
// normal terminate
return Worker.prototype.terminate.apply(this, arguments);
}
// creates NEW WORKER with the same URL as itself
worker.restart = function() {
return makeWorkerSmart(workerURL);
}
return worker;
}
要同时从 worker 端检测终止,您将需要 运行 每个 worker 中的此代码:
function makeInsideWorkerSmart(workerScope) {
var oldClose = workerScope.close;
workerScope.close = function() {
postMessage("SECRET_WORKER_TERMINATE_MESSAGE");
oldClose();
}
}
makeInsideWorkerSmart(self);
当 worker 以 close
.
结束时,这将向主 window 发送消息
你可以这样使用它:
var worker = makeWorkerSmart(url);
worker.terminate();
worker.postMessage("test"); // throws error!
重新启动工作器
关于重新启动 worker:从技术上讲,如果不将其保存在某个地方,则从以前的某个状态开始是不可能的。我提出我在上面实施的这个解决方案:
worker.terminate();
worker = worker.restart();
您也可以通过这种方式克隆 worker,因为它不会停止原始 worker。
web worker终止后,为什么我调用它postMessage
不报错?
是否可以在没有构造函数的情况下使用现有的已终止实例重新启动 worker new Worker("same-worker.js")
?
const myWorker = new Worker("my-worker.js");
myWorker.addEventListener("message", function(event) {
const message = event.data;
console.log("from worker", message);
myWorker.terminate();
myWorker.postMessage("");
// what happens here, is only silence
// Why not throw error?
});
myWorker.postMessage(""); //start it, maybe receive a response
编辑:我问的是这种特殊设计的基本原理。 XHR、WebSocket 和 WebRTC 在尝试对已终止的实例执行操作时会立即抛出异常。
根据文档,工人的 terminate 方法
immediately terminates the Worker. This does not offer the worker an opportunity to finish its operations; it is simply stopped at once.
我认为,由于实例即使处于这种死状态,它仍然存在,因此执行 postMessage
不会抛出,但由于您的工作人员未处理任何操作,它只会什么都不做。
据我所知,无法恢复工作人员,但如果您希望能够随意恢复它,您也可以通过消息设置一个布尔值来暂停您的处理。
tl;dr jsFiddle
我无法回答为什么,因为我不是编写javascript标准的人。但是没有任何迹象表明工人是否已经终止。
正在检测终止
如果您需要检测此状态,则必须创建您自己的 API。我建议将这个基于简单函数的草稿作为起点:
//Override worker methods to detect termination
function makeWorkerSmart(workerURL) {
// make normal worker
var worker = new Worker(workerURL);
// assume that it's running from the start
worker.terminated = false;
// allows the worker to terminate itself
worker.addEventListener("message", function(e) {
if(e.data == "SECRET_WORKER_TERMINATE_MESSAGE") {
this.terminated = true;
console.info("Worker killed itself.");
}
});
// Throws error if terminated is true
worker.postMessage = function() {
if(this.terminated)
throw new Error("Tried to use postMessage on worker that is terminated.");
// normal post message
return Worker.prototype.postMessage.apply(this, arguments);
}
// sets terminate to true
// throws error if called multiple times
worker.terminate = function() {
if(this.terminated)
throw new Error("Tried to terminate terminated worker.");
this.terminated = true;
// normal terminate
return Worker.prototype.terminate.apply(this, arguments);
}
// creates NEW WORKER with the same URL as itself
worker.restart = function() {
return makeWorkerSmart(workerURL);
}
return worker;
}
要同时从 worker 端检测终止,您将需要 运行 每个 worker 中的此代码:
function makeInsideWorkerSmart(workerScope) {
var oldClose = workerScope.close;
workerScope.close = function() {
postMessage("SECRET_WORKER_TERMINATE_MESSAGE");
oldClose();
}
}
makeInsideWorkerSmart(self);
当 worker 以 close
.
你可以这样使用它:
var worker = makeWorkerSmart(url);
worker.terminate();
worker.postMessage("test"); // throws error!
重新启动工作器
关于重新启动 worker:从技术上讲,如果不将其保存在某个地方,则从以前的某个状态开始是不可能的。我提出我在上面实施的这个解决方案:
worker.terminate();
worker = worker.restart();
您也可以通过这种方式克隆 worker,因为它不会停止原始 worker。