最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Js中setTimeout()和setInterval() 何時(shí)被調(diào)用執(zhí)行的用法

 更新時(shí)間:2013年04月12日 09:16:09   作者:  
本篇文章,小編將為大家介紹Js中setTimeout()和setInterval() 何時(shí)被調(diào)用執(zhí)行的用法,有需要的朋友可以參考一下

定義
setTimeout()和setInterval()經(jīng)常被用來處理延時(shí)和定時(shí)任務(wù)。setTimeout() 方法用于在指定的毫秒數(shù)后調(diào)用函數(shù)或計(jì)算表達(dá)式,而setInterval()則可以在每隔指定的毫秒數(shù)循環(huán)調(diào)用函數(shù)或表達(dá)式,直到clearInterval把它清除。
從定義上我們可以看到兩個(gè)函數(shù)十分類似,只不過前者執(zhí)行一次,而后者可以執(zhí)行多次,兩個(gè)函數(shù)的參數(shù)也相同,第一個(gè)參數(shù)是要執(zhí)行的code或句柄,第二個(gè)是延遲的毫秒數(shù)。
很簡(jiǎn)單的定義,使用起來也很簡(jiǎn)單,但有時(shí)候我們的代碼并不是按照我們的想象精確時(shí)間被調(diào)用的,很讓人困惑


簡(jiǎn)單示例
看個(gè)簡(jiǎn)單的例子,簡(jiǎn)單頁面在加載完兩秒后,寫下Delayed alert!

復(fù)制代碼 代碼如下:

setTimeout('document.write("Delayed alert!");', 2000);

看起來很合理,我們?cè)倏磦€(gè)setInterVal()方法的例子
復(fù)制代碼 代碼如下:

var num = 0;
        var i = setInterval(function() {
            num++;
            var date = new Date();
            document.write(date.getMinutes() + ':' + date.getSeconds() + ':' + date.getMilliseconds() + '<br>');
            if (num > 10)
                clearInterval(i);
        }, 1000);

頁面每隔1秒記錄一次當(dāng)前時(shí)間(分鐘:秒:毫秒),記錄十次后清除,不再記錄。考慮到代碼執(zhí)行時(shí)間可能記錄的不是執(zhí)行時(shí)間,但時(shí)間間隔應(yīng)該是一樣的,看看結(jié)果
復(fù)制代碼 代碼如下:

:38:116
:39:130
:40:144
:41:158
:42:172
:43:186
:44:200
:45:214
:46:228
:47:242
:48:256

為什么
時(shí)間間隔幾乎是1000毫秒,但不精確,這是為什么呢?原因在于我們對(duì)JavaScript定時(shí)器存在一個(gè)誤解,JavaScript其實(shí)是運(yùn)行在單線程的環(huán)境中的,這就意味著定時(shí)器僅僅是計(jì)劃代碼在未來的某個(gè)時(shí)間執(zhí)行,而具體執(zhí)行時(shí)機(jī)是不能保證的,因?yàn)轫撁娴纳芷谥?,不同時(shí)間可能有其他代碼在控制JavaScript進(jìn)程。在頁面下載完成后代碼的運(yùn)行、事件處理程序、Ajax回調(diào)函數(shù)都是使用同樣的線程,實(shí)際上瀏覽器負(fù)責(zé)進(jìn)行排序,指派某段程序在某個(gè)時(shí)間點(diǎn)運(yùn)行的優(yōu)先級(jí)。
我們把效果放大一下看看,添加一個(gè)耗時(shí)的任務(wù)
復(fù)制代碼 代碼如下:

function test() {
            for (var i = 0; i < 500000; i++) {
                var div = document.createElement('div');
                div.setAttribute('id', 'testDiv');
                document.body.appendChild(div);
                document.body.removeChild(div);
            }
        }
        setInterval(test, 10);
        var num = 0;
        var i = setInterval(function() {
            num++;
            var date = new Date();
            document.write(date.getMinutes() + ':' + date.getSeconds() + ':' + date.getMilliseconds() + '<br>');
            if (num > 10)
                clearInterval(i);
        }, 1000);

我們又加入了一個(gè)定時(shí)任務(wù),看看結(jié)果
復(fù)制代碼 代碼如下:

:9:222
:12:482
:16:8
:19:143
:22:631
:25:888
:28:712
:32:381
:34:146
:35:565
:37:406

這下效果明顯了,差距甚至都超過了3秒,而且差距很不一致。
我們可以可以把JavaScript想象成在時(shí)間線上運(yùn)行。當(dāng)頁面載入的時(shí)候首先執(zhí)行的是頁面生命周期后面要用的方法和變量聲明和數(shù)據(jù)處理,在這之后JavaScript進(jìn)程將等待更多代碼執(zhí)行。當(dāng)進(jìn)程空閑的時(shí)候,下一段代碼會(huì)被觸發(fā)

除了主JavaScript進(jìn)程外,還需要一個(gè)在進(jìn)程下一次空閑時(shí)執(zhí)行的代碼隊(duì)列。隨著頁面生命周期推移,代碼會(huì)按照?qǐng)?zhí)行順序添加入隊(duì)列,例如當(dāng)按鈕被按下的時(shí)候他的事件處理程序會(huì)被添加到隊(duì)列中,并在下一個(gè)可能時(shí)間內(nèi)執(zhí)行。在接到某個(gè)Ajax響應(yīng)時(shí),回調(diào)函數(shù)的代碼會(huì)被添加到隊(duì)列。JavaScript中沒有任何代碼是立即執(zhí)行的,但一旦進(jìn)程空閑則盡快執(zhí)行。定時(shí)器對(duì)隊(duì)列的工作方式是當(dāng)特定時(shí)間過去后將代碼插入,這并不意味著它會(huì)馬上執(zhí)行,只能表示它盡快執(zhí)行。
知道了這些后,我們就能明白,如果想要精確的時(shí)間控制,是不能依賴于JavaScript的setTimeout函數(shù)的。

重復(fù)的定時(shí)器
使用 setInterval() 創(chuàng)建的定時(shí)器可以使代碼循環(huán)執(zhí)行,到有指定效果的時(shí)候,清除interval就可以,如下例
復(fù)制代碼 代碼如下:

var my_interval = setInterval(function () {
            if (condition) {
                //..........
            } else {
                clearInterval(my_interval);
            }
        }, 100);

但這個(gè)方式的問題在于定時(shí)器的代碼可能在代碼再次被添加到隊(duì)列之前還沒有執(zhí)行完成,結(jié)果導(dǎo)致循環(huán)內(nèi)的判斷條件不準(zhǔn)確,代碼多執(zhí)行幾次,之間沒有停頓。不過JavaScript已經(jīng)解決這個(gè)問題,當(dāng)使用setInterval()時(shí),僅當(dāng)沒有該定時(shí)器的其他代碼實(shí)例時(shí)才將定時(shí)器代碼插入隊(duì)列。這樣確保了定時(shí)器代碼加入到隊(duì)列的最小時(shí)間間隔為指定間隔。

這樣的規(guī)則帶來兩個(gè)問題

1.1. 某些間隔會(huì)被跳過
2.2.多個(gè)定時(shí)器的代碼執(zhí)行之間的間隔可能比預(yù)期要小
為了避免這兩個(gè)缺點(diǎn),我們可以使用setTimeout()來實(shí)現(xiàn)重復(fù)的定時(shí)器
復(fù)制代碼 代碼如下:

setTimeout(function () {
            //code
            setTimeout(arguments.callee, interval);
        }, interval)

這樣每次函數(shù)執(zhí)行的時(shí)候都會(huì)創(chuàng)建一個(gè)新的定時(shí)器,第二個(gè)setTimeout()調(diào)用使用了agrument.callee 來獲取當(dāng)前實(shí)行函數(shù)的引用,并設(shè)置另外一個(gè)新定時(shí)器。這樣做可以保證在代碼執(zhí)行完成前不會(huì)有新的定時(shí)器插入,并且下一次定時(shí)器代碼執(zhí)行之前至少要間隔指定時(shí)間,避免連續(xù)運(yùn)行。
復(fù)制代碼 代碼如下:

setTimeout(function () {
            var div = document.getElementById('moveDiv');
            var left = parseInt(div.style.left) + 5;
            div.style.left = left + 'px';
            if (left < 200) {
                setTimeout(arguments.callee, 50);
            }
        }, 50);

這段定時(shí)器代碼每次執(zhí)行的時(shí)候,把一個(gè)div向右移動(dòng)5px,當(dāng)坐標(biāo)大于200的時(shí)候停止。

  • 網(wǎng)頁編輯器ckeditor和ckfinder配置步驟分享

    網(wǎng)頁編輯器ckeditor和ckfinder配置步驟分享

    ckeditor+ckfinder配置用法,現(xiàn)在ckeditor是互聯(lián)網(wǎng)上應(yīng)用比較廣泛的網(wǎng)頁編輯器了,這里介紹下配置方法,需要的朋友可以參考下
    2012-05-05
  • IE不支持getElementsByClassName最終完美解決方案

    IE不支持getElementsByClassName最終完美解決方案

    目前可以這么解決,判斷瀏覽器支不支持這個(gè)方法,如果支持就不管;如果不支持,就在document對(duì)象里加入getElementsByClassName這個(gè)方法,按興趣的朋友可以了解下
    2012-12-12
  • 注釋的藝術(shù)——JS里直接寫HTML,無需轉(zhuǎn)義

    注釋的藝術(shù)——JS里直接寫HTML,無需轉(zhuǎn)義

    注釋的藝術(shù)——JS里直接寫HTML,無需轉(zhuǎn)義...
    2006-12-12
  • javascript實(shí)現(xiàn)用戶必須勾選協(xié)議實(shí)例講解

    javascript實(shí)現(xiàn)用戶必須勾選協(xié)議實(shí)例講解

    這篇文章主要介紹了javascript實(shí)現(xiàn)用戶必須勾選協(xié)議實(shí)例講解,寫頁面的時(shí)候經(jīng)常會(huì)用到,有感興趣的同學(xué)可以學(xué)習(xí)下
    2021-03-03
  • 深入理解javascript變量聲明

    深入理解javascript變量聲明

    本文是談?wù)勛约簩?duì)于javascript中變量聲明的一些看法、感想和理解,算是自己的一個(gè)小總結(jié)吧,分享出來給大家,希望對(duì)小伙伴們能有所幫助
    2014-11-11
  • 深入理解javascript中return的作用

    深入理解javascript中return的作用

    這篇文章主要介紹了javascript中return的作用,有需要的朋友可以參考一下
    2013-12-12
  • 分析Node.js connect ECONNREFUSED錯(cuò)誤

    分析Node.js connect ECONNREFUSED錯(cuò)誤

    最近在準(zhǔn)備Angularjs +node.js demo的時(shí)候在我的mac開發(fā)中 遇見此錯(cuò)誤
    2013-04-04
  • JavaScript中的各種操作符使用總結(jié)

    JavaScript中的各種操作符使用總結(jié)

    這里我們說的操作符包括算數(shù)運(yùn)算符和邏輯操作符等,包括布爾與賦值等,為大家進(jìn)行了JavaScript中的各種操作符使用總結(jié),需要的朋友可以參考下
    2016-05-05
  • 淺談JavaScript Array對(duì)象

    淺談JavaScript Array對(duì)象

    這篇文章主要介紹了JavaScript Array對(duì)象的相關(guān)資料,需要的朋友可以參考下
    2014-12-12
  • 最新評(píng)論

    德钦县| 盐亭县| 毕节市| 板桥市| 淄博市| 富川| 潞西市| 翁牛特旗| 沂南县| 临西县| 江安县| 保山市| 呼伦贝尔市| 临朐县| 汾阳市| 新竹市| 黄山市| 色达县| 咸宁市| 白河县| 时尚| 高陵县| 乌拉特前旗| 礼泉县| 石门县| 重庆市| 天等县| 达尔| 田林县| 勐海县| 宽城| 曲水县| 察哈| 定边县| 定西市| 陇西县| 哈巴河县| 连城县| 宜兰县| 商丘市| 绥芬河市|