日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
setTimeout的誤差堆積測(cè)試和分析

前段時(shí)間做了一個(gè)團(tuán)購(gòu)秒殺倒計(jì)時(shí)的js展現(xiàn)的例子(http://www.blogjava.net/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ì)算誤差。

成都創(chuàng)新互聯(lián)2013年至今,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目成都做網(wǎng)站、網(wǎng)站建設(shè)網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元興國(guó)做網(wǎng)站,已為上家服務(wù),為興國(guó)各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:028-86922220

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

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

     
     
     
     
    1.  
     
  •  
  •  
  •  

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

     
     
     
     
     
  •  
  • 其實(shí)為什么javascript的定時(shí)器會(huì)出現(xiàn)所謂的不可靠或偏差的情況,這是可以理解的,最主要的問題是它們并不是所謂的線程,其實(shí)
    javascript是運(yùn)行于單線程的環(huán)境中,而定時(shí)器只是計(jì)劃代碼在未來某個(gè)執(zhí)行的時(shí)間,執(zhí)行的時(shí)間點(diǎn)是不能被保證的,因?yàn)樵陧?yè)面的生命周期中,不同時(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í)行的

     
     
     
     
    1. function showtime(){  
    2. // code 1...  
    3. f = setTimeout('showtime()',200); //200毫秒后要插入執(zhí)行代碼對(duì)瀏覽器的js隊(duì)列  
    4. // 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ì)跳過

    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)用

     
     
     
     
    1. setTimeOut(function(){  
    2. code處理...  
    3. setTimeOut(arguments.callee,interval);  
    4. },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章。


    文章標(biāo)題:setTimeout的誤差堆積測(cè)試和分析
    標(biāo)題網(wǎng)址:http://www.dlmjj.cn/article/dpidghh.html