类似Gmail的倒数计时器无效

时间:2013-04-05 00:08:35

标签: javascript jquery timer countdown

我一直在尝试重新创建倒数计时器,类似于当你从互联网断开连接时使用的一个gmail。 ajax请求失败,然后它开始一个短暂的倒计时然后再发一个ajax请求,如果它再次失败,那么开始更长的倒计时等等。一旦达到确定的倒计时值(比如说1分钟),倒计时将保持在1分钟,直到互联网连接恢复或服务器恢复。

我不想使用插件,因为此代码将嵌入到空间有限的微控制器中,并且由于实际原因也不希望将其作为外部文件放置,即使jQuery库已经是外部的。

所有内容都应触发onload,并自动继续(即不会使用任何控制输入)。

到目前为止,我已经开发了代码,如果ajax请求成功或立即失败,但是如果ajax请求状态存在延迟(例如让服务器关闭),则执行我想要的操作,浏览器将不会生成立即结果,我的代码失败。

我知道我上面说的是因为我实际上把服务器关闭了,并且在Mozilla Firefox上得到了firebug的帮助,看到ajax结果(成功或失败)没有立即触发但是等待几秒钟。

请帮忙!

HTML代码:

<div id='tempFail' ></div>

jQuery代码:

$(document).ready(function()
{ 
    //do when DOM ready - http://api.jquery.com/ready/

    var timerSpeed = [1000, 5000, 10000, 20000, 30000, 60000];

    // current time in ms since 1/1/1970, plus the initial reload interval
    var end = (new Date).getTime() + timerSpeed[1];  
    var n=0;
    var m=0;

    setInterval(function() 
    {
        var now = (new Date).getTime();
        // Current time left to re-load in seconds, sometimes it goes to negative values, see below 

        var secLeft = Math.floor(( end - now ) / 1000);

        // if secLeft is negative multiply by zero...equal to secLeft=0, this will produce an error of one second approximately      
        var timeToload = (secLeft < 0) ? secLeft * 0 : secLeft;  

        if (n!=0) 
        { 
            //check for failed or delayed request\n\       

            $('#tempFail').html('Failed or delayed response. Will auto load in: '+timeToload+ ' seconds!'); 
        }

        if( (secLeft)<=0)// if reload time is reached do
        {                      

            if (m==0)//used to prevent multiple continue reloads when ajax request status is not yet defined
            {                            

                m=1;    

                $.getScript('script_vars.js').done(function (data) 
                {         
                    //if request succeeded
                    m=0;
                    n = 0;
                    end = (new Date).getTime() + timerSpeed[1];  
                    // Time to load after the initial interval set above
                    $('#tempFail').html(''); 

                //other code on success  here         
                })
                .fail(function() 
                {      
                    //if request failed
                    m=0;
                    n ++;
                    if(n==6) n=5;

                   switch(n){         //timer delay for failed request\n\


                     case 1:

                       end = (new Date).getTime() + timerSpeed[1];
                       break;

                     case 2:

                        end = (new Date).getTime() + timerSpeed[2];
                       break;

                     case 3:

                        end = (new Date).getTime() + timerSpeed[3];
                       break;

                     case 4:

                       end = (new Date).getTime() + timerSpeed[4];
                       break;

                     case 5:

                        end = (new Date).getTime() + timerSpeed[5];
                       break;  
                  } 


               });      

         }
        }                


        }, 1000);

     });

3 个答案:

答案 0 :(得分:2)

你问了一个例子,所以我编写了以下内容,你可能希望将该函数的内容包装在另一个函数中,这样你就可以重复它/不必担心命名空间/等等。没有测试所以不要指望没有bug!

对每个动作使用window.setTimeout,将每个阶段分成它自己的功能,以便更容易地遵循代码路径。

$(document).ready(function () { // http://api.jquery.com/ready/
    var $tempFail = $('#tempFail'),
        delay = [1000, 5000, 10000, 20000, 30000, 60000],
        delay_index = 0,
        delay_ends = 0,
        inform_user_ref = null,
        inform_user = function inform_user() {
            var now = (new Date).getTime(),
                delta; // for difference, calculate later
            if (delay_ends > now) { // if we're waiting for a retry
                delta = Math.floor((delay_ends - now ) / 1000); // calculate time to wait
                $tempFail.html('Failed or delayed response. Will auto load in: '+delta+ ' seconds!'); // let people know
                window.setTimeout(inform_user, 200); // loop countdown timer
                // can fast refresh this as it's just a countdown
            }
        },
        get_success = function () {
            $tempFail.html('');
            // .. code on success
        },
        get_fail = function () {
            delay_index < 5 && ++delay_index; // increment delay_index
            get_initialise(); // retry
            window.clearTimeout(inform_user_ref); // remove any old countdown timer
            inform_user_ref = inform_user(); // and display new countdown
        },
        get_try = function () {
            $.getScript('script_vars.js')
                .done(get_success)
                .fail(get_fail);
        },
        get_initialise = function () {
            delay_ends = (new Date).getTime() + delay[delay_index];
            window.setTimeout(get_try, delay[delay_index]); // retry
        };
    get_initialise(); // initial
});

答案 1 :(得分:0)

哇!保罗先生你的代码很疯狂。我做了一些调整,让它在我需要时完美地工作。

  1. 在ajax成功上添加了以下内容:

  2.   

    delay_index = 0; // reset delay_index

    get_initialise(); // retry
    

    所以如果一切正常,我会每5秒运行一次代码。

    2

    添加了两个新变量:let_cntDwn_endajax_rqst_status以避免倒计时数字跳跃(在开始倒计时之前让倒数完成)并在ajax请求未给出任何结果时显示消息分别。

    以下是新代码:

    $(document).ready(function(){ //do when DOM ready - http://api.jquery.com/ready/
    
    
    
        var $tempFail = $('#tempFail'),
            delay = [5000, 5000, 10000, 20000, 30000, 60000],
            delay_index = 0,
            delay_ends = 0,
            inform_user_ref = null,
            let_cntDwn_end = 0,      
            ajax_rqst_status = 0,    //ajax success or failure triggered
            inform_user = function inform_user() {
                var now = (new Date).getTime(),
                    delta; // for difference, calculated later
                if (delay_ends > now) { // if we're waiting for a retry
                    let_cntDwn_end = 1;
                    delta = Math.floor((delay_ends - now ) / 1000); // calculate time to wait
                    if (ajax_rqst_status==0){
                      $tempFail.html('Failed response. Will auto load in: '+delta+ ' seconds!'); // let people know
                      window.setTimeout(inform_user, 900); // loop countdown timer
                      // can fast refresh this as it's just a countdown
                    }
                }
                else {let_cntDwn_end = 0; get_try();}
            },
            get_success = function () {
                   ajax_rqst_status =0;
                   $tempFail.html('');
                   // .. code on success           
    
                   delay_index = 0; //reset delay_index
                   get_initialise(); // retry           
            },
            get_fail = function () {                        
                ajax_rqst_status =0;
                delay_index < 5 && ++delay_index; // increment delay_index
                get_initialise(); // retry  
                window.clearTimeout(inform_user_ref); // remove any old countdown timer
                inform_user_ref = inform_user(); // and display new countdown
    
            },
            get_try = function () {
                if (let_cntDwn_end == 0){
    
                        ajax_rqst_status=1;
                       $tempFail.html('Waiting for Ajax request success or failure'); // let people know    
    
                $.getScript('script_vars.js')
                    .done(get_success)
                    .fail(get_fail);
                    }
            },
            get_initialise = function () {
                delay_ends = (new Date).getTime() + delay[delay_index];
                window.setTimeout(get_try, delay[delay_index]); // retry
            };
        get_initialise(); // initial
    });
    

答案 2 :(得分:0)

还有JS lib通过监视ajax请求来为你处理这个问题。

https://github.com/HubSpot/offline