<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    于吉吉的技術(shù)博客

    建造高性能門戶網(wǎng)

      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      65 隨筆 :: 6 文章 :: 149 評(píng)論 :: 0 Trackbacks

    前段時(shí)間做了一個(gè)團(tuán)購秒殺倒計(jì)時(shí)的js展現(xiàn)的例子(http://m.tkk7.com/dongbule/archive/2011/12/06/365687.html),倒計(jì)時(shí)的方式主要使用setTimeout的函數(shù)進(jìn)行遞歸實(shí)現(xiàn),由于是使用setTimeout,所以根據(jù)js的引擎,這其中將可能存在一定的時(shí)間誤差,一個(gè)誤差不要緊,兩個(gè)誤差無所謂,但長(zhǎng)時(shí)間的誤差堆積將出現(xiàn)較大的偏離值,所以根據(jù)秒殺倒計(jì)時(shí)的例子,做了一個(gè)簡(jiǎn)單的模擬的誤差堆積測(cè)試,并在各個(gè)瀏覽器中進(jìn)行測(cè)試。
    鑒于秒殺倒計(jì)時(shí)都是以一秒為單位,所以下面的例子也都以1000毫秒為計(jì)算,當(dāng)然各個(gè)瀏覽器的實(shí)現(xiàn)和附加代碼的編寫也會(huì)造成一定的時(shí)間誤差,這部分誤差也合并在setTimeout的實(shí)現(xiàn)里面計(jì)算誤差。

    <div id="show" style="width:500px;"></div>
    <script>
    var w = 1000;
    var second = 0;
    function showtime(){    
    showtime.curr
    =  +new Date();    
    setTimeout('showtime()',
    1000);    
    document.getElementById(
    "show").innerHTML+=second +"    "+(showtime.curr-(showtime.last||showtime.curr)-1000)+"    <br/>";    
    showtime.last
    =showtime.curr;    
    second
    ++;
    }
    showtime();
    </script>

    可以看到在各個(gè)不同的瀏覽器在不同的秒數(shù)中出現(xiàn)不同的誤差,當(dāng)然這個(gè)跟我本機(jī)的瀏覽器和環(huán)境有關(guān)



    下面再將這些誤差值進(jìn)行疊加測(cè)試

    <div>
    <div id="show" style="width:500px;"></div>
    </div>
    <script>
    var w = 1000;
    var i = 0;
    function showtime(){
        showtime.curr
    =  +new Date();
        f 
    = setTimeout('showtime()',1000);
        w
    +=(showtime.curr-(showtime.last||showtime.curr)-1000);
        document.getElementById(
    "show").innerHTML+=i+"   "+(showtime.curr-(showtime.last||showtime.curr)-1000)  +"    "+w+" 

    <br/>
    ";
        showtime.last
    =showtime.curr;
        i
    ++;
    }
    showtime();
    </script>



    IE和chrome相對(duì)較為穩(wěn)定,不知道是不是我本機(jī)環(huán)境的原因,firefox出現(xiàn)了很多大偏差,可以選擇定時(shí)清空這個(gè)誤差值來處理,或是采用鏈?zhǔn)降膕etTimeOut()來處理。

    <div id="show" style="width:300px;"></div>
    <script>
    var w = 1000;
    var i = 0;
    var f ;
    var t ;
    var k = 0;
    function showtime(){
        showtime.curr
    =  +new Date();
        f 
    = setTimeout('showtime()',1000);
        w
    +=(showtime.curr-(showtime.last||showtime.curr)-1000);
        document.getElementById(
    "show").innerHTML+=i+"   "+w+"  "+(showtime.curr-(showtime.last||showtime.curr)-1000)  +"    <br/>";
        showtime.last
    =showtime.curr;
        i
    ++;
    }
    function round(){
        
    if(k!=0){
            clearTimeout(f);
            showtime();
            document.getElementById(
    "show").innerHTML+="  clear<br/>";
            w
    =0;
        }
        setTimeout('round()',
    10000);
        k
    ++;
    }
    showtime();
    round();
    </script>

    其實(shí)為什么javascript的定時(shí)器會(huì)出現(xiàn)所謂的不可靠或偏差的情況,這是可以理解的,最主要的問題是它們并不是所謂的線程,其實(shí)
    javascript是運(yùn)行于單線程的環(huán)境中,而定時(shí)器只是計(jì)劃代碼在未來某個(gè)執(zhí)行的時(shí)間,執(zhí)行的時(shí)間點(diǎn)是不能被保證的,因?yàn)樵陧撁娴纳芷谥校煌瑫r(shí)間可能存在其他代碼,或各個(gè)瀏覽器的內(nèi)核控制住javascript進(jìn)程。

    settimeout幾個(gè)見解
    1、setTimeOut  !=  thread | 時(shí)間片的并發(fā)調(diào)用
    2、javascript以單線程的方式運(yùn)行于瀏覽器的javascript引擎中
    3、setTimeout 只是把要執(zhí)行的代碼在設(shè)定的時(shí)間點(diǎn)插入js引擎維護(hù)的代碼隊(duì)列
    4、setTimeout 插入代碼隊(duì)列并不意味著代碼就會(huì)立馬執(zhí)行的

    function showtime(){
    // code 1...
    f = setTimeout('showtime()',200);     //200毫秒后要插入執(zhí)行代碼對(duì)瀏覽器的js隊(duì)列
    // code 2...
    }
    以上面面的代碼為例,說說它的執(zhí)行流程
    Code 1 -> 200毫秒后通知瀏覽器有隊(duì)列插入   ->   Code 2   ->   showtime()  ->    …
    這個(gè)種重復(fù)遞歸可能會(huì)造成2個(gè)問題:
    1 . 時(shí)間間隔可能小于定時(shí)調(diào)用的代碼的執(zhí)行時(shí)間
    2 . 時(shí)間間隔或許會(huì)跳過

    時(shí)間間隔或許會(huì)跳過


    5ms : code1 代碼執(zhí)行完畢,200ms后有定時(shí)器進(jìn)入隊(duì)列
    205ms : 定時(shí)器進(jìn)入隊(duì)列,code2繼續(xù)
    300ms : function代碼結(jié)束,定時(shí)器從隊(duì)列中取出,執(zhí)行
    405ms : 第二個(gè)定時(shí)器進(jìn)入隊(duì)列,第一個(gè)定時(shí)器的代碼在執(zhí)行中
    605ms : 第三個(gè)定時(shí)器意圖進(jìn)入隊(duì)列失敗,這個(gè)點(diǎn)的settimeout丟失

    為了避免這2個(gè)問題,可以采用鏈?zhǔn)絪etTimeOut()進(jìn)行調(diào)用
    setTimeOut(function(){
    code處理...
    setTimeOut(arguments.callee,interval);
    },interval);
    這個(gè)模式鏈?zhǔn)綏l用setTimeOut(),每次函數(shù)執(zhí)行的時(shí)候都會(huì)創(chuàng)建一個(gè)新的定時(shí)器,第二個(gè)setTimeOut調(diào)用使用了arguments.callee來獲取當(dāng)前執(zhí)行的函數(shù)引用,并為其設(shè)置另外一個(gè)定時(shí)器,這樣的好處在于,在前一個(gè)定時(shí)器執(zhí)行完之前不會(huì)向隊(duì)列中插入新的定時(shí)器代碼,確保不會(huì)有任何的確實(shí)間隔,而且它可以保證在下一次定時(shí)器代碼執(zhí)行前,至少等待指定的間隔,避免連續(xù)的運(yùn)行。



    //-------------//
    秒殺的定時(shí)器已經(jīng)通過檢測(cè)正式運(yùn)行了,博客記錄得不好,表達(dá)不是很清楚,關(guān)于setTimeOut的函數(shù)主要參考了《JavaScript高級(jí)程序設(shè)計(jì)(第2版)》的第18章。
    posted on 2012-01-10 15:15 陳于喆 閱讀(3548) 評(píng)論(6)  編輯  收藏 所屬分類: web開發(fā)

    評(píng)論

    # re: 對(duì)setTimeout的誤差堆積測(cè)試和簡(jiǎn)單分析 2012-01-10 23:00 rox
    這個(gè)夠?qū)I(yè),學(xué)習(xí)一下!  回復(fù)  更多評(píng)論
      

    # re: 對(duì)setTimeout的誤差堆積測(cè)試和簡(jiǎn)單分析 2012-01-11 09:06 tb
    很專業(yè)啊   回復(fù)  更多評(píng)論
      

    # re: 對(duì)setTimeout的誤差堆積測(cè)試和簡(jiǎn)單分析 2012-01-11 09:20 HiMagic!
    這個(gè)在我的博客也提到過,當(dāng)頁面內(nèi)容較多時(shí)偏差更嚴(yán)重。如果只靠setTimeout的interval倒計(jì)時(shí),而不看本地Date當(dāng)前值,相差更嚴(yán)重。  回復(fù)  更多評(píng)論
      

    # re: 對(duì)setTimeout的誤差堆積測(cè)試和簡(jiǎn)單分析 2012-01-12 15:17 第一時(shí)尚網(wǎng)
    學(xué)習(xí)了。。。謝謝博主  回復(fù)  更多評(píng)論
      

    # re: 對(duì)setTimeout的誤差堆積測(cè)試和簡(jiǎn)單分析 2013-09-27 20:47 購物導(dǎo)航
    購物導(dǎo)航http://www.5a77.com/
    不好意思呵,來推廣一下自己的網(wǎng)站
    也支持一下你的文章,寫得這么好,剛好路過呵  回復(fù)  更多評(píng)論
      

    # re: 對(duì)setTimeout的誤差堆積測(cè)試和簡(jiǎn)單分析 2015-08-11 14:36 hirain
    代碼中: showtime.curr= +new Date();是什么意思,為什么要寫個(gè)加號(hào)?  回復(fù)  更多評(píng)論
      

    主站蜘蛛池模板: 国产片免费在线观看| 亚洲人和日本人jizz| 亚洲女女女同性video| 免费看的成人yellow视频| 久久午夜无码免费| 一边摸一边爽一边叫床免费视频 | 亚洲乳大丰满中文字幕| 色吊丝永久在线观看最新免费| 欧洲精品99毛片免费高清观看| 97se亚洲国产综合自在线| 亚洲AV无码国产精品色午友在线 | 亚洲制服中文字幕第一区| 亚洲无码高清在线观看| 国产在线不卡免费播放| 免费无码A片一区二三区| 激情婷婷成人亚洲综合| 亚洲一区二区三区免费观看| 亚洲一级二级三级不卡| 国产亚洲福利精品一区| 一二三四影视在线看片免费| 男性gay黄免费网站| 亚洲av无码专区在线电影| 在线A亚洲老鸭窝天堂| 久久久久久国产精品免费免费 | 亚洲网站免费观看| 国产网站在线免费观看| 青苹果乐园免费高清在线| 国产91色综合久久免费分享| 美丽姑娘免费观看在线观看中文版| 免费播放在线日本感人片| 中国一级毛片视频免费看| 久久免费视频一区| 精品国产呦系列在线观看免费| 一级做受视频免费是看美女| 一级人做人a爰免费视频 | 国产亚洲精品自在久久| 国产亚洲一区二区三区在线观看| 国产亚洲精品激情都市| 99无码人妻一区二区三区免费 | 亚洲精品视频免费观看| 亚洲综合久久夜AV |