JSON data if/else parse

筅森魡賤 提交于 2019-12-13 04:24:52

问题


I am doing some long polling (ajax) and I am looping the following portion of code.. There is code being executed above and below. This code is part of an internal messaging system. A certain portion of the page wil blink when a message arrives. If the user checks the message, it will remove the dash_notify from the JSON response, which needs to turn off the blinking. See below:

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

The following JSON response that gets sent to this code is:

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

It understand the initial blink IF the above data gets passed. If the following gets passed:

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

Then it throws an error:

Uncaught ReferenceError: timer is not defined 

I cannot figure out how to fix the "else" portion working properly. If the code is initiated when the full dash_notify:1 response is sent, it works perfect. The button will blink, then if the user checks the message, it will no longer send dash_notify:1 and the button stops blinking. But if the code is initiated when dash_notify:1 is NOT set, it doesn't know what to do with the ClearInterval.

Basically I need the else portion fixed.

I have tried using different typeOf === undefined snippets, but it doesn't work.

Any help is appreciated.

Thank you!

EDIT:

This is currently working.. Timer is now defined above the statement

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

                            var x = '#dash_notif_blink';

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

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

This is working, but sometimes it trys to kill the timer but it doesn't actually do it. This happens every so often.


回答1:


Looks like it's not working because timer doesn't exist outside your inner blinking function. I'm making an assumption here that you don't have var timer; somewhere outside the blinking function, which is strongly likely given the error you're getting.

Why this is happening:

If I'm right, and you're not declaring timer anywhere else in your code, then var timer is being implicitly added to the beginning of the blinking function:

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

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

That makes timer a local variable inside blinking. Since you never pass it out of the closure, it doesn't exist once you're outside that function. So either you need to pull timer into the outer context (option 1) or make it available from inside blinking (option 2).

What to do:

If you want access to timer outside of that closure, you'll have to do one of two things:

1: Declare timer outside of blinking:

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

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

2: Make it the return value of 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);
}

Either one of these will work, and is more or less the same in terms of polluting the outer namespace. I prefer Option 2, because I feel like it's easier to work with a local variable until you need to return it.


Edit:

Your comment said the loop runs infinitely, which means you're creating a brand new interval and reassigning the timer variable every time. This is a separate problem from the one I described above. The old interval is still out there, timer just doesn't point to it anymore. So how can clearInterval(timer) clear out all those intervals? It can't, it can only clear the most recent one.

Basically, you've got a whole bunch of timers all trying to make the thing blink at once.

How you deal with this depends on what you're trying to do. The simplest thing would be to keep no more than one interval running at once, which means you have to clear timer every time.

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

If you need multiple timers running, you'll have to keep track of them all in an array or something:

var timers = [];
//...
   function blinking(x) {
        timers.push(setInterval(blink, 10));
//...
} else if (!data.dash_notify) {
   timers.forEach(function(timer) {
       clearInterval(timer);
   });
}



回答2:


Not sure what you did wrong with your typeof check since you did not actually show the whole code, but it should look something like this:

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



回答3:


Basically define your variable timer before you enter your checking procedure (loop?):

var timer;

... some code ...

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

You can call clearInterval( whatever ) without any consequences. Even if whatever is null, undefined, string and so on. Just make sure timer exist.

Passing an invalid ID to clearTimeout does not have any effect (and doesn't throw an exception). (MDN)




回答4:


You're getting that error because timer is only declared/initialized in the blinking function. In the place where you call clearInterval(timer), timer doesn't exist.




回答5:


This is now working beautifully. *Thank you to everyone who helped!*

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');

                }                   


来源:https://stackoverflow.com/questions/14224263/json-data-if-else-parse

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!