簡體   English   中英

無法停止在setTimeout上運行的功能

[英]Can not stop the function running on 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;
  }
}

這應該照顧超時和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;
  }
}

你不重視doSyncsetTimeOut功能和函數內聲明的,所以不是全局。

請執行下列操作:

  • 聲明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);
}

由於您一直在運行超時,因此您需要使用某種終結器。

您可以執行以下操作:

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

好..您不需要為此使用對象,但是也許這使您對如何創建某種數據綁定有了一個想法。

就像freedom-m在問題的評論中所說的那樣,如果我在setTimeout()中調用checkSync函數,它將很好地工作。

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

問題是通知setTimeout停止(以調用clearTimeout),這似乎需要定期運行checkSync(),以便我們可以決定是否需要調用clearTimeout。 現在,它檢查復選框狀態是否每10秒更改一次,以決定是否執行sync()

謝謝大家花時間在此上。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM