简体   繁体   中英

Debug a Javascript issue properly? (most likely client-side)

This issue is most likely client-side, but I'm not sure about that. This is about an auction website and I get data (price, time left) every second with a WebSocket (node.js Server).

If the price changes, my script automatically fires an event where the countdown and price of this auction flashes and my array timers gets refreshed with the seconds left ( auction.duration ):

if ($('.price' + timers[i][0]).data('curr_text') !== $('.price' + timers[i][0]).text()) 
{
$(".flashing" + timers[i][0]).toggle("highlight").toggle("highlight");
timers[i][1] = auction.duration;        
}

So, I was afk some hours and some of the auction timers went to zero (shows up like this 00:00:00 ), but not all timers. As I refreshed the page, these auctions were still running, so this is most likely a client-side JavaScript problem. And also a huge problem, because a user thinks the auction is over, refreshes the page and will notice that it's actually still running.

I can just guess that this issue occurs, because of some timing issues, but I'm not sure. Also I don't know how to debug this issue, because I can't stare on the screen for hours to wait for this to happen. So I would appreciate suggestions to debug this.

I think it's also helpful to show you my full code and maybe you see something that I'm missing:

// prevent flashing after page loaded
$(".refresh-item").each(function() {
$this = $(this);
var id = $this.attr("data-id"); 
$('.price' + $this.attr("data-id")).data('curr_text', $('.price' + id).text());
});
// format timer
var formatSeconds = function(secs){
    var pad = function(n) {
        return (n < 10 ? "0" + n : n);
    };
    var h = Math.floor(secs / 3600);
    var m = Math.floor((secs / 3600) % 1 * 60); // Reminder of an hour of seconds x 60
    var s = Math.floor((secs / 60) % 1 * 60); // Reminder of a minute of seconds x 60
    return pad(h) +":"+ pad(m) +":"+ pad(s);
};  

var timers = [];
var socket = io.connect('http://xxx.rhcloud.com:8000/',{'forceNew':true });
socket.on('stream', function (data) {
    $.each(data.streamArray,function(index,auction){    
    duration = auction.duration;
    num_rows = data.streamArray.length;

    if (duration > 0)
    {
    var price_retail = $("#" + auction.id).attr("data-retail"); 

    var calc = auction.price.toFixed(2);
    var price_calc = calc.toString().replace(/\./g, ',');   
    $(".price" + auction.id).html(price_calc + "€");            
    $(".discount" + auction.id).html(discount + "%");

    if (timers.length < num_rows)
    timers.push([auction.id, auction.duration]);
    for(i in timers) 
    {                   
        if ($('.price' + timers[i][0]).data('curr_text') !== $('.price' + timers[i][0]).text()) 
        {
        $(".flashing" + timers[i][0]).toggle("highlight").toggle("highlight");
        timers[i][1] = auction.duration;        
        }
    }   
    $('.price' + auction.id).data('curr_text', $('.price' + auction.id).text());        
    } 
    else
    {
    $(".sold" + auction.id).html("<div class='sold'>SOLD</div>").fadeOut('fast').fadeIn('fast');            
    }
    });
});
function timerCount() {
    for(i in timers) {              
        if(timers[i][1] <= 0) {
        delete timers[i]; // if timer seconds is less than 1, delete it.
        } else {            
        timers[i][1]--; // else, decrease it by 1 second.
        duration_html = formatSeconds(timers[i][1]);        
        $(".duration" + timers[i][0]).html(duration_html);              
        }   
    }
}
setInterval(timerCount, 1000);

It's also important to mention that a red sign called "SOLD" will appear if an auction is actually over (see end of socket stream). But this also didn't happen. The timer just stopped and went to 00:00:00 . So it has to do something with the array that delete timers[i] was triggered too soon, I guess?

Additional information: I forgot to mention that these timers reset to approx. 15-16 seconds every time a user placed a bid. So the array timers is alive for a long time. And this array loops every single second.

As I understand, your timers got deleted every 1 minute by this code:

function timerCount() {
    for(i in timers) {              
        if(timers[i][1] <= 0) {
            delete timers[i]; // if timer seconds is less than 1, delete it.
        } else {            
            timers[i][1]--; // else, decrease it by 1 second.
            duration_html = formatSeconds(timers[i][1]);        
            $(".duration" + timers[i][0]).html(duration_html);              
        }   
    }
}

Where are you decreasing minutes and hours?

And the second thing - you cannot guarantee that time on client and server is synchronized so you should perform some AJAX requests for time in timers and adjust your timers with some interval.

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