我有 2 个 setInterval 函数(好吧,抱歉,我认为里面的代码可能是多余的,并且会使问题本地化:/但无论如何,这里是:
$('#armStatus').click(function(){
armingloop = setInterval(function () {
if ($checkbox.is(':checked ')) {
$.post('/request', {
key_pressed: "arming_status"
}).done(function (reply) {
$arm.empty().append("<h3>The Arming Status is " + reply + "</h3>").show();
$arm.show();
});
} else {
$arm.hide();
}
}, 3000);
});
和
$('#monitor').click(function () {
bigloop = setInterval(function () {
var checked = $('#status_table tr [id^="monitor_"]:checked');
if (checked.index() === -1 || checked.length === 0) {
clearloop(bigloop);
$('#monitor').button('enable');
} else {
//$('#monitor').button('enable'); //enable the monitor button
(function loop(i) {
//monitor element at index i
monitoring($(checked[i]).parents('tr'));
//delay of 3 seconds
setTimeout(function () {
//when incremented i is less than the number of rows, call loop for next index
if (++i < checked.length) loop(i);
}, 3000);
}(0)); //start with 0
}
}, index * 3000); //loop period
});
function clearloop(loopname){
bigloop= window.clearInterval(loopname);
}
两者都将由不同的选择器触发。我观察到,当bigloop
被激活,并且稍后也激活armingloop
时,我的中的状态更新功能
受到影响(例如,状态回复被错误的元素捕获。)monitoring
bigloop
请注意,我还有一个 setTimer
。
我的问题是,如何确保任意 2 个 setInterval
是隔离的并且不会互相影响?
最佳答案
你根本不能,因为他们无法保证订单。它们与其他事件(包括重绘等)一起添加到事件队列中,并调用先发生的事件。
更好的实现是在主循环中抛出监视器正在监听的 CustomEvent
。
简化:
// global flag for monitoring
var isMonitoring = true,
armingloop;
// the function we use to update monitor.
// This will be called every time we send an event
function updateMonitor(e) {
/* ... update ... */
// ie. e.detail.mydata
}
// Start listening to 'monitor' event. If received, call
// the function above (only reference the function).
window.addEventListener('monitor', updateMonitor, false);
// The main loop. Self-triggering for loop by calling
// setTimeout.
// Do the stuff you need and then, if monitor is
// enabled create an event and dispatch (send) it.
function loop() {
/* ... main stuff ... */
// do we monitor?
if (isMonitoring) {
// something need to be updated on monitor so
// create an event
var myEvent = new CustomEvent('monitor', {
detail: {
/* here you can provide needed data for monitor */
"mydata": data /*, other data */
},
/* If you don't need to send any data in particular,
just leave detail empty like this:
detail: {},
*/
bubbles: false,
cancelable: true
});
// send event to anyone who listens..
window.dispatchEvent(myEvent);
}
//here you can use a use a flag to stop the loop,
//f.ex. if 'isLooping' === true then setTimeout...
armingloop = setTimeout(loop, 3000);
}
function toggleMonitor() {
// Call this from the toggle button, or modify to
// reflect checkbox-status etc...
isMonitoring = !isMonitoring;
}
//start everything:
loop();
我将示例从 setInterval
更改为 setTimeout
以避免堆栈/阻塞。另请记住,Javascript 是单线程的(有一些与此处无关的异常(exception)情况)。因此,setTimeout
是更好的选择(从循环内部调用它)。
关于javascript - 如何保证两个setInterval()不会互相影响?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16581800/