0

我正在做一些长轮询(ajax),我正在循环下面的代码部分。上面和下面都有代码正在执行。此代码是内部消息传递系统的一部分。当消息到达时,页面的某个部分会闪烁。如果用户检查消息,它将从 JSON 响应中删除 dash_notify,这需要关闭闪烁。见下文:

if (data.dash_notify == '1') {
    var x = '#dash_notif_blink';

    function blinking(x) {
        timer = setInterval(blink, 10);

        function blink() {
            x.fadeOut(400, function () {
                x.fadeIn(400);
            });
        }
    }

    console.log("initiate_dash");
    blinking($(x));
} else if (!data.dash_notify) {
    console.log("good");

    clearInterval(timer);
}

发送到此代码的以下 JSON 响应是:

{"current_date_time":"January 8, 2013 - 4:02 pm","dash_notify":"1"}

如果上述数据通过,它会理解初始闪烁。如果以下通过:

{"current_date_time":"January 8, 2013 - 4:02 pm"}

然后它抛出一个错误:

Uncaught ReferenceError: timer is not defined 

我无法弄清楚如何修复“其他”部分正常工作。如果在发送完整的 dash_notify:1 响应时启动代码,则它可以完美运行。按钮会闪烁,然后如果用户检查消息,它将不再发送 dash_notify:1 并且按钮停止闪烁。但是如果代码在没有设置 dash_notify:1 时启动,它不知道如何处理 ClearInterval。

基本上我需要修复其他部分。

我尝试过使用不同的 typeOf === undefined 片段,但它不起作用。

任何帮助表示赞赏。

谢谢!

编辑:

这目前正在工作.. Timer 现在在语句上方定义

if(data.dash_notify == '1'){

                            var x = '#dash_notif_blink';

                        console.log("initiate_dash");
                        blinking($(x));

                        }else if (typeof timer != "undefined" && timer) { 
                            clearInterval(timer);
    }               
                    }

这是可行的,但有时它会尝试终止计时器,但实际上并没有这样做。这种情况经常发生。

4

5 回答 5

3

看起来它不起作用,因为在您的内部功能timer之外不存在。blinking我在这里假设您在函数之外没有任何var timer;地方blinking,这很可能是因为您遇到了错误。

为什么会这样:

如果我是对的,并且您没有timer在代码中的其他任何地方声明,那么var timer将被隐式添加到blinking函数的开头:

function blinking(x) {
    var timer;
    timer = setInterval(blink, 10);

    function blink() {
        x.fadeOut(400, function () {
            x.fadeIn(400);
        });
    }
}

这会timer在内部产生一个局部变量blinking。由于您永远不会将其从闭包中传递出去,因此一旦您在该函数之外,它就不存在了。因此,要么您需要拉timer入外部上下文(选项 1),要么从内部提供它blinking(选项 2)。

该怎么办:

如果您想访问timer该闭包之外的内容,则必须执行以下两项操作之一:

1:timer在外部声明blinking

 var timer = null;
 if (data.dash_notify == '1') {
    var x = '#dash_notif_blink';

    function blinking(x) {
        //etc...

2:使其成为的返回值blinking

var t;

if (data.dash_notify == '1') {
    var x = '#dash_notif_blink';

    function blinking(x) {
        var timer = setInterval(blink, 10); //note the var keyword for best practice

        function blink() {
            x.fadeOut(400, function () {
                x.fadeIn(400);
            });
        }

        return timer;
    }

    console.log("initiate_dash");
    t = blinking($(x));

} else if (!data.dash_notify) {
    console.log("good");    
    clearInterval(t);
}

这些中的任何一个都可以工作,并且在污染外部命名空间方面或多或少是相同的。我更喜欢选项 2,因为我觉得使用局部变量更容易,直到您需要返回它。


编辑:

您的评论说循环无限运行,这意味着您正在创建一个全新的间隔并timer每次都重新分配变量。这是与我上面描述的问题不同的问题。旧的间隔仍然存在,timer只是不再指向它。那么如何clearInterval(timer)清除所有这些间隔呢?它不能,它只能清除最近的一个。

基本上,你有一大堆计时器都试图让这个东西同时闪烁。

你如何处理这个取决于你想要做什么。最简单的方法是一次运行不超过一个间隔,这意味着您必须timer每次都清除。

//same as option 1 above except for `clearInterval(timer)` at the 
//beginning of `blinking`
var timer = null;

if (data.dash_notify == '1') {
    var x = '#dash_notif_blink';

    function blinking(x) {
        clearInterval(timer); 
        timer = setInterval(blink, 10);

如果您需要运行多个计时器,则必须以数组或其他方式跟踪它们:

var timers = [];
//...
   function blinking(x) {
        timers.push(setInterval(blink, 10));
//...
} else if (!data.dash_notify) {
   timers.forEach(function(timer) {
       clearInterval(timer);
   });
}
于 2013-01-08T22:06:13.750 回答
0

这现在工作得很好。 *感谢所有帮助过的人!*

if(data.dash_notify === '1' && t === null ){

                    var x = '#dash_notif_blink';

                    function blinking(x) {
                        var timer = setInterval(blink, 10); //note the var keyword for best practice

                        function blink() {
                            x.fadeOut(400, function () {
                                x.fadeIn(400);
                            });
                        }
                        return timer;
                    }

                    console.log('initiate_dash_alert');

                    // Data is passed. Parse to see if dash alert should be called. Secondary protection for
                    // multiple timer creation.
                    if(t){return;}else{t = blinking($(x));}




                }else if (!data.dash_notify){    
                    clearInterval(t);
                    console.log('clear_dash_alert');
                    t = null;
                }else{
                    console.log(t);
                    console.log('no_push_events');

                }                   
于 2013-01-10T21:25:01.040 回答
0

不确定您的 typeof 检查做错了什么,因为您实际上并没有显示整个代码,但它应该看起来像这样:

if (typeof timer != "undefined" && timer) { 
    clearInterval(timer);
}
于 2013-01-08T21:25:41.843 回答
0

timer基本上在您进入检查程序(循环?)之前定义您的变量:

var timer;

... some code ...

if ( data.dash_notify && data.dash_notify == '1') {
    ...
} else if (!data.dash_notify) {
    clearInterval(timer);
}

您可以拨打电话clearInterval( whatever ) 而不会产生任何后果。即使whatevernull, undefined, 字符串等等。只要确保timer存在。

将无效 ID 传递给 clearTimeout 没有任何效果(并且不会引发异常)。(MDN)

于 2013-01-08T21:32:36.690 回答
0

您收到该错误是因为timer仅在blinking函数中声明/初始化。在你打电话的地方clearInterval(timer)timer不存在。

于 2013-01-08T21:33:39.583 回答