简体   繁体   中英

JavaScript Comparison returning same and different

I am comparing Current Sub and New Sub. It gets the CurrentSub from a php file and waits for 4 seconds before getting the NewSub from the same file.

When I run this code, it pops up with both the alert for it being the same and the alert for it being different.

I don't understand how it can be the same but different? I'm printing the variables put on screen and they are identical.

Any help would be appreciated.

setInterval(function() {
    var CurrentSub = "<?php echo $Name[1] ; ?>";
    setTimeout(function() {
        var NewSub = "<?php echo $Name[1] ; ?>";
        if (NewSub != CurrentSub) {
            window.alert("different");
            setTimeout(function() {
                $('.subText').html(NewSub);
            }, 200)

            document.getElementById("Sub1Move").style.display = "block";
            document.getElementById("Sub1").style.display = "none";
            $("#Sub1Move").animate({
                marginTop: "-=34px",
            }, 1900, function() {
                document.getElementById("Sub1").style.display = "block";
            });
            setTimeout(function() {
                $("#Sub1Move").stop();
                document.getElementById("Sub1").style.display = "block";
                document.getElementById("Sub1Move").style.display = "none";
                document.getElementById("Sub1Move").style.marginTop = "34px";

            }, 2000);
            var CurrentSub = "<?php echo $Name[1] ; ?>";
        };
        if (NewSub == CurrentSub) {
            window.alert("same");
        };
    }, 4000);

    $('.test').html(NewSub);
    $('.test1').html(CurrentSub);

}, 500);

setTimeout(function() {
    $('.subText').html(CurrentSub);
}, 200);

The first statement is executed before:

if (NewSub != CurrentSub) {

so that the different alert is shown. Then at the end there is:

var CurrentSub = "<?php echo $Name[1] ; ?>";

so that now CurrentSub and NewSub are equal and so correctly the if statement below evaluates to true:

if (NewSub == CurrentSub) {

Your setInterval and setTimeout are creating a race condition. You have new setTimeout for 4seconds created at each setInterval called. In the end, you have 8 new setTimeouts called before the first one is executed. This is a result of each setInterval taking 500ms while the nested setTimeout takes 4s. Basically, this code smells because you have to keep comparing things when they've already changed. Try not to execute a new setInterval before the last one has finished. So, either lengthen the setInterval timeout or shorten the nested setTimeout .

the problem is the the variables that get referred to in the closures. and the hoisting of declarations your code nests something like this.

function scope1(){
    var CurrentSub // local 1
    function scope2()
    {
       var NewSub // local 2
       if(NewSub comparison CurrentSub)//you think you are referring to "local 1" but since you are redeclaring it on this function  you are actually referring to "local 3"
       {
            CurrentSub IS undefined at this point
       }
       var CurrentSub // local 3 .. redeclaration of a var in local scope, is created as undefined in the beginning of the scope, only to be defined at this point
    }
}

the simplest solution is to remove var from the second var CurrentSub to allow the function to refer to the external variable, instead of creating a new for the inner scope.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM