Web Worker 中的 clearInterval 不停止计时器
clearInterval in web worker not stopping timer
我的问题在这里被问过一次:
clearInterval in webworker is not working
解决方案似乎很清楚,但出于某种原因,它还不适用于我。我有一个网络工作者正在将一个间隔发送回主线程。我希望能够使用 clearInterval 停止间隔,但它不起作用。
我的设置与上一个问题中的建议完全相同,但仍然没有成功。我添加了一些 console.logs 来验证我在正确的块中。 “停止”在应该的时候记录到控制台,但计时器不会停止发布到主线程。
有人能看出这是怎么回事吗?
谢谢
worker.js
let mytimer;
self.onmessage = function(evt) {
if (evt.data == "start") {
console.log("start")
var i = 0;
mytimer = setInterval(function() {
i++;
postMessage(i);
}, 1000);
} else if (evt.data == "stop") {
console.log("stop")
clearInterval(mytimer);
}
};
然后当 timer.time 高于或低于某个值(在本例中为 2000)时,我从我的 React 挂钩中调用它
main.js
const worker = new myWorker()
useEffect(() => {
worker.addEventListener('message', function(e) {
//from interval in the worker
console.log('Message from Worker: ' + e.data);
})
if(timer.time > 2000){
worker.postMessage("start")
}else{
worker.postMessage("stop")
}
},[timer.time])
您还应该在开始新的间隔时清除间隔。如果你不这样做,你之前的间隔将保持运行,你将失去清除它的能力:
let mytimer;
self.onmessage = function(evt) {
console.log(evt.data)
if(evt.data === 'start' || evt.data === 'stop') {
clearInterval(mytimer);
}
if (evt.data == "start") {
var i = 0;
mytimer = setInterval(function() {
i++;
postMessage(i);
}, 1000);
}
};
您应该创建一个工人实例,并将其存储为 ref:
const worker = useRef()
useEffect(() => {
worker.current = new myWorker()
return () => {
worker.current.terminate();
}
}, [])
不相关,但除此之外,每当 timer.time
更改时,useEffect
都会添加一个新的事件侦听器,而不清除前一个。我会把它分成 2 useEffect
个块,一个用于发送(可以与 worker 的创建相结合),另一个用于接收。
useEffect(() => {
const eventHander = e => {
//from interval in the worker
console.log('Message from Worker: ' + e.data);
}
worker.current.addEventListener('message', eventHander)
return () => {
worker.current.removeEventListener('message', eventHander)
}
}, [])
useEffect(() => {
worker.current.postMessage(timer.time > 2000 ? 'start' : 'stop')
}, [timer.time])
我不确定网络工作者,但我非常熟悉在 useEffect
中使用间隔。由于每次依赖项更改 (timer.time
) 时都会调用 useEffect
,因此您需要将间隔存储在 useRef 中,除非您要在依赖项下次更改之前清除它
我的问题在这里被问过一次: clearInterval in webworker is not working
解决方案似乎很清楚,但出于某种原因,它还不适用于我。我有一个网络工作者正在将一个间隔发送回主线程。我希望能够使用 clearInterval 停止间隔,但它不起作用。
我的设置与上一个问题中的建议完全相同,但仍然没有成功。我添加了一些 console.logs 来验证我在正确的块中。 “停止”在应该的时候记录到控制台,但计时器不会停止发布到主线程。
有人能看出这是怎么回事吗?
谢谢
worker.js
let mytimer;
self.onmessage = function(evt) {
if (evt.data == "start") {
console.log("start")
var i = 0;
mytimer = setInterval(function() {
i++;
postMessage(i);
}, 1000);
} else if (evt.data == "stop") {
console.log("stop")
clearInterval(mytimer);
}
};
然后当 timer.time 高于或低于某个值(在本例中为 2000)时,我从我的 React 挂钩中调用它
main.js
const worker = new myWorker()
useEffect(() => {
worker.addEventListener('message', function(e) {
//from interval in the worker
console.log('Message from Worker: ' + e.data);
})
if(timer.time > 2000){
worker.postMessage("start")
}else{
worker.postMessage("stop")
}
},[timer.time])
您还应该在开始新的间隔时清除间隔。如果你不这样做,你之前的间隔将保持运行,你将失去清除它的能力:
let mytimer;
self.onmessage = function(evt) {
console.log(evt.data)
if(evt.data === 'start' || evt.data === 'stop') {
clearInterval(mytimer);
}
if (evt.data == "start") {
var i = 0;
mytimer = setInterval(function() {
i++;
postMessage(i);
}, 1000);
}
};
您应该创建一个工人实例,并将其存储为 ref:
const worker = useRef()
useEffect(() => {
worker.current = new myWorker()
return () => {
worker.current.terminate();
}
}, [])
不相关,但除此之外,每当 timer.time
更改时,useEffect
都会添加一个新的事件侦听器,而不清除前一个。我会把它分成 2 useEffect
个块,一个用于发送(可以与 worker 的创建相结合),另一个用于接收。
useEffect(() => {
const eventHander = e => {
//from interval in the worker
console.log('Message from Worker: ' + e.data);
}
worker.current.addEventListener('message', eventHander)
return () => {
worker.current.removeEventListener('message', eventHander)
}
}, [])
useEffect(() => {
worker.current.postMessage(timer.time > 2000 ? 'start' : 'stop')
}, [timer.time])
我不确定网络工作者,但我非常熟悉在 useEffect
中使用间隔。由于每次依赖项更改 (timer.time
) 时都会调用 useEffect
,因此您需要将间隔存储在 useRef 中,除非您要在依赖项下次更改之前清除它