如何停止该setTimeout函数的执行?

4
我使用下面的函数来检查JSON文件的状态。它每8秒运行一次(使用setTimeout)来检查文件是否发生了变化。一旦JSON的状态变为“success”,我就不再想继续调用该函数。有人能告诉我如何做到这一点吗?我怀疑这涉及到clearTimeout的使用,但我不确定如何实现。
干杯!
  $(function() {
    var checkBookStatus = function() {
       var job_id = "#{@job.job_id}";
       var msg = $('.msg');
       var msgBuilding = $('#msg-building');
       var msgQueuing = $('#msg-in-queue');
       var msgSuccessful = $('#msg-successful-build');
       var msgError = $('#msg-error'); 
       $.ajax({ 
         url: '/jobs/'+job_id+'/status.json',

           datatype: 'JSON',
           success:function(data){
             if (data.status == "failure")  {
               msg.hide();          
               msgError.show();
             }
             else if (data.status == "#{Job.queue}")  {
            msg.hide();          
            msgQueuing.show();
         }
             else if (data.status == "#{Job.building}")  {
            msg.hide();          
            msgBuilding.show();
         }             
         else if (data.status == "#{Job.failure}")  {
             msg.hide();          
             msgError.show();
         }
         else if (data.status == "#{Job.success}")  {
             msg.hide();          
             msgSuccessful.show();

              }                    
           },       
       }).always(function () {
            setTimeout(checkBookStatus, 8000);
      });
    };    
   checkBookStatus();    
  });
6个回答

6

t = setTimeout(checkBookStatus, 8000); 当你决定停止计时器时使用 clearTimeout(t);


确保代码写为 t = setTimeout(...) 而不是 <b>var<b> t = setTimeout(...),其中的变量t必须设置为全局变量。 - Ahmed Jolani
超时将调用checkBookStatus函数,清除必须在checkBookStatus函数内部进行。很明显,除非函数被“已调用”,否则超时的清除不会发生。如果它还没有被调用,为什么要请求停止它呢? - Ahmed Jolani
@LeeKowalkowski,你让我一遍又一遍地思考啊!当他第一次调用函数时,在函数外部var t将被创建并且可以访问,在第一次调用setTimeout之后,他可以在外部计数然后使用clearTimeout(t),当然这只在第一次调用之后才有效。 - Ahmed Jolani
然后使用计数器,c=0;在外部,现在在调用超时检查之前检查计数器,在调用之后增加计数器c - Ahmed Jolani
在我上一条评论中,我并不想清除超时,我只是想停止调用setTimeout,但现在我明白了你的意思,你的解决方案是正确的。 - Ahmed Jolani
显示剩余3条评论

5

使用clearTimeout

例如,您定义了:

id = setTimeout(checkBookStatus, 8000);  

那么您可以通过以下方式删除此函数:
clearTimeout(id)

2

使用之前由 setTimeout 返回的值来调用 clearTimeout。这将会给你类似以下的内容:

$(function() {
  var timeoutID;
  var checkBookStatus = function () {
      […]
      else if (data.status == "#{Job.success}")  {
          clearTimeout(timeoutID);
      […]
       }).always(function () {
        timeoutID = setTimeout(checkBookStatus, 8000);
      […]

2
当您使用setTimeout时,请按照以下方式使用:
var myTime = setTimeout(checkBookStatus, 8000);

要清除它,只需:

clearTimeout(myTime);

2

在最后调用checkBookStatus()之前,再调用一次:var interval = setInterval(checkBookStatus, 8000);。然后在成功时可以clearInterval(interval)

不要使用setTimeout进行迭代。

很多答案建议只使用clearTimeout(),但是,在超时已经过期后检查状态,没有超时需要清除。您需要在always()函数中不调用setTimeout()而不是清除任何内容。所以你可以在你的always()函数内重新检查状态,但你的data对象不在那里的范围内。最好是在你的checkBookStatus()函数外部使用setInterval()

$(function() {
    var checkBookStatus = function() {
        var job_id = "#{@job.job_id}";
        var msg = $('.msg');
        var msgBuilding = $('#msg-building');
        var msgQueuing = $('#msg-in-queue');
        var msgSuccessful = $('#msg-successful-build');
        var msgError = $('#msg-error'); 
        $.ajax({ 
            url: '/jobs/'+job_id+'/status.json',
            datatype: 'JSON',
            success:function(data){
                if (data.status == "failure")  {
                    msg.hide();          
                    msgError.show();
                }
                else if (data.status == "#{Job.queue}")  {
                    msg.hide();          
                    msgQueuing.show();
                }
                else if (data.status == "#{Job.building}")  {
                    msg.hide();          
                    msgBuilding.show();
                }             
                else if (data.status == "#{Job.failure}")  {
                    msg.hide();          
                    msgError.show();
                }
                else if (data.status == "#{Job.success}")  {
                    msg.hide();          
                    msgSuccessful.show();
                    clearInterval(interval);
                }                    
            }       
        });
    };    
    var interval = setInterval(checkBookStatus, 8000);    
    checkBookStatus();
});

0

以下应该可以正常工作...

setTimeout函数会返回setTimeout函数的一个实例。将这个值保存在一个变量中,并在需要防止事件再次触发时将其传递给clearTimeout函数。

例如:

    var t = setTimeout(1000, someFunction);
...

//after you no longer need the timeout to fire, call

clearTimeout(t);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接