javascript - 如何保证两个setInterval()不会互相影响?

标签 javascript jquery

我有 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/

相关文章:

javascript - 如何获取Google Apps脚本的文本内容?

javascript - 通过 WebApi 将媒体批量上传到 Azure Blob 存储

javascript - PostgreSQL 物化 View 在刷新时阻塞读取

javascript - jquery删除部分url

JavaScript:如何控制进度速度?

javascript - 从使用 jQuery 的 php 网站提取数据。无相关来源信息

jquery - 基本的 jQuery SlideUp 和 SlideDown 让我抓狂!

javascript - 随机选择的事件结果

javascript - 运行 PHP 代码,根据文本元素的值从数据库获取值

javascript - 动态创建的网页不起作用