简体   繁体   English

无法停止在setTimeout上运行的功能

[英]Can not stop the function running on setTimeout

I have the following javascript function that runs every 10 seconds to sync some data with the database. 我有以下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);
}

This function starts to execute when a Activate Sync checkbox is checked. 选中“ Activate Sync复选框后,此功能开始执行。 but once it is running, it does not stop when unckecking the checkbox. 但是一旦运行,取消选中该复选框时它不会停止。 Below is what I already have tried that does do anything and the function gets executing until the page is reloaded (the checkbox is unchecked by default) 以下是我已经尝试执行的所有操作,并且函数将一直执行到页面重新加载为止(默认情况下未选中此复选框)

function checkSync(){
  var doSync;

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

This should take care of the timeout and of the ajax request: 这应该照顾超时和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;
  }
}

You didn't attach doSync to the setTimeOut function and declared it within the function, so not globally. 你不重视doSyncsetTimeOut功能和函数内声明的,所以不是全局。

Do the following: 请执行下列操作:

  • Declare var doSync; 声明var doSync; outside your functions to set it globally. 在您的功能之外进行全局设置。
  • Edit your last line of the function to this: return setTimeout(sync, 10000); 将函数的最后一行编辑为: return setTimeout(sync, 10000);

Now doSync will contain the ID value returned by setTimeOut. 现在doSync将包含setTimeOut返回的ID值。

Example of a working code: 工作代码示例:

// 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);
}

you need to use some kind of terminator since you are constantly running timeouts. 由于您一直在运行超时,因此您需要使用某种终结器。

you could do something like this: 您可以执行以下操作:

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

well.. you don't need to use an object for this but maybe this gives you an idea of how you could create some kind of data binding. 好..您不需要为此使用对象,但是也许这使您对如何创建某种数据绑定有了一个想法。

Just as freedomn-m said in the comments of the question, It works fine if I call checkSync function in the setTimeout() . 就像freedom-m在问题的评论中所说的那样,如果我在setTimeout()中调用checkSync函数,它将很好地工作。

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

The proble was to inform the setTimeout to stop (to call the clearTimeout) which seems like there was a need to run checkSync() regularly so that we could decide if it is needed to call clearTimeout. 问题是通知setTimeout停止(以调用clearTimeout),这似乎需要定期运行checkSync(),以便我们可以决定是否需要调用clearTimeout。 It now checks if the checkbox state is changed every 10 seconds to decide wether do the sync() or not. 现在,它检查复选框状态是否每10秒更改一次,以决定是否执行sync()

Thank you all for putting your time on this. 谢谢大家花时间在此上。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM