为什么我的setInterval函数没有停止

时间:2015-05-22 09:50:29

标签: javascript ajax

我需要在javascript中编写一个setInterval函数。这是代码:

var myTimer=setInterval(function(){ 
        var time=0;

        $.ajax({
            url:'...'
            type: "POST",
            dataType:"",
            success: function (response) {

                if(response=="true" || time>=10000){

                    clearInterval(myTimer);
                }
                time=time+1000;


            },
            error: function () {
                alert("FAIL");
            }
        });


        },1000);

我不知道为什么它不会在clearInterval中停止。有人可以帮帮我吗?

2 个答案:

答案 0 :(得分:2)

您已声明代码“进入'if'”,因此我认为实际上正在进行clearInterval调用。

鉴于此,最可能的解释是 区间被清除(毕竟,select isn't broken),但在第一个"true"响应之前,你已经< strong>已经进行了多次ajax调用,而你看到的其他调用是在间隔被清除之前安排的那些。

例如,您的代码运行并且:

  1. 触发ajax呼叫#1,这需要一秒多的时间才能完成
  2. 关闭ajax电话#2
  3. Ajax call#1完成但不是"true"
  4. 关闭ajax电话#3
  5. Ajax call#2完成并且"true",清除间隔
  6. Ajax call#3完成
  7. 混合两个独立的异步间隔(一个通过setInterval,另一个通过ajax)会产生麻烦。

    如果目标是每秒发出一次请求并在你回来"true"时停止,我会让成功处理程序安排下一次调用,例如:

    (function() {
        var time = 0;
        var started = 0;
    
        start();
    
        function start() {
            started = Date.now();
            $.ajax({
                url: '...'
                type: "POST",
                dataType: "",
                success: function(response) {
                    if (response != "true") {
                        // Schedule the next call to occur one second after we
                        // started the previous call; or almost immediately if
                        // the call took more than a second to complete
                        setTimeout(start, Math.max(0, 1000 - (Date.now() - started)));
                    }
                    time = time + 1000;
                },
                error: function() {
                    alert("FAIL");
                }
            });
        }
    
    })();
    

答案 1 :(得分:0)

让我说明预期和实​​际情况,以使事情更清楚。

情景#1

下图显示了所有ajax请求在一秒钟之前完成的情况。您会注意到ajax回调success(或error)函数将仅在clearInterval之前执行(这是您一直期望的)。

enter image description here

情景#2

当你的一些ajax请求花费超过一秒时(可能会发生这种情况),那么你的ajax回调可以在 / 之前 / 之前触发 - 并且clearInterval,这会让您觉得setInterval 没有停止

enter image description here

请注意,您的time变量是无用的,因为它是一个函数范围的变量,您可以在每个函数调用时初始化为0。即使它是一个全局变量,它也只会清除第11个成功函数回调中的间隔,并且没有什么能保证这11个成功请求需要多长时间。

<强>解决方案

作为T.J. Crowder suggested,最好在前一个成功回调中安排下一个ajax调用,这可以保证你的ajax请求按顺序触发(一次只有一个)。

注意:因为您在回答后编辑了问题,所以您还需要编辑if条件,如下所示:

success: function(response) {
    if (response != "true" && time < 10000) {
    setTimeout(start, Math.max(0, 1000 - (Date.now() - started)));
    }
}