无法停止在setTimeout上运行的函数

时间:2017-10-23 12:21:18

标签: javascript jquery checkbox settimeout

我有以下javascript函数,每10秒运行一次,以便与数据库同步一些数据。

function sync(){
  latestID = $("#dataDiv tbody tr:first").attr("data-key");
  var url = '<?=$model['fn']?>';
  $.ajax({
    url: url,
    type: 'post',
    dataType: 'json',
    data:{latestID: latestID},
    success: function (result) {
      //Do some stuff
    }
  });
  setTimeout(sync, 10000);
}

选中Activate Sync复选框后,此功能开始执行。但是一旦它运行,它在解除复选框时不会停止。  下面是我已经尝试过做的任何事情,函数会一直执行,直到页面重新加载(默认情况下取消选中该复选框)

function checkSync(){
  var doSync;

  if($('#keepChecking').is(':checked')){
    doSync = sync();
    //alert("checked"); return false;
  }else{
    clearTimeout(doSync);
    return false;
    //alert("not checked"); return false;
  }
}

4 个答案:

答案 0 :(得分:0)

这应该处理超时和ajax请求:

var ajaxRequest,
    syncTimeout;

function sync(){
  latestID = $("#dataDiv tbody tr:first").attr("data-key");
  var url = '<?=$model['fn']?>';
  ajaxRequest = $.ajax({
    url: url,
    type: 'post',
    dataType: 'json',
    data:{latestID: latestID},
    success: function (result) {
      //Do some stuff
    }
  });
  syncTimeout = setTimeout(sync, 10000);
}

function checkSync(){
  if($('#keepChecking').is(':checked')){
    sync();
    //alert("checked"); return false;
  }else{
    clearTimeout(syncTimeout);
    ajaxRequest.abort();
    return false;
    //alert("not checked"); return false;
  }
}

答案 1 :(得分:-1)

您没有将doSync附加到setTimeOut函数并在函数中声明它,因此不是全局的。

执行以下操作:

  • 在您的函数之外声明var doSync;以全局设置它。
  • 将此功能的最后一行编辑为:return setTimeout(sync, 10000);

现在doSync将包含setTimeOut返回的ID值。

工作代码示例:

// Declare the variable globally
var mySync;

function setFunction() {
    // Set mySync to the ID returned by setTimeout (to use clearTimeout)
    mySync = setTimeout(function(){}, 3000);
}

function clearFunction() {
    // Clear timeout with the ID
    clearTimeout(mySync);
}

答案 2 :(得分:-1)

你需要使用某种终结器,因为你经常运行超时。

你可以这样做:

// let's grab the html elements
const counter = document.getElementById('counter');
const start = document.getElementById('start');
const stop = document.getElementById('stop');

// define a counter
let count = 0;

// function that runs the payload
const runTimer = terminator => {
  counter.textContent = ++count;
  // on each run assign the new timeout to the terminator object
  terminator.timeout = setTimeout(()=> runTimer(terminator), 100);
};

// define an object we use to access the most recent timeout
const terminator = {};
// when i click start → run the payload
start.addEventListener('click', e => runTimer(terminator));
// when i click stop → terminate the last created timeout reference.
stop.addEventListener('click', e => clearTimeout(terminator.timeout));
<div id="counter">0</div>
<br>
<button id="start">start</button>
<button id="stop">stop</button>

嗯..你不需要为此使用一个对象,但也许这可以让你了解如何创建某种数据绑定。

答案 3 :(得分:-1)

正如 freedomn-m 在问题的评论中所说,如果我在 setTimeout()中调用 checkSync 函数,它会正常工作

setTimeout(checkSync, <?=$model['aud'];?>);

问题是通知setTimeout停止(调用clearTimeout),这似乎需要定期运行checkSync(),以便我们可以决定是否需要调用clearTimeout。它现在检查复选框状态是否每10秒更改一次,以决定是否执行 sync()

谢谢大家把时间花在这上面。