国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

chrome下的Javascript的任務機制

nidaye / 1992人閱讀

摘要:在第一次循環的時候并沒有被賦值,所以是,在第二次循環的時候,定時器其實清理的是上一個循環的定時器。所以導致每次循環都是清理上一次的定時器,而最后一次循環的定時器沒被清理,導致一直輸出。

Javascript Evet Loop 模型

setTimeout()最短的事件間隔是4ms
setInterval()最短的事件間隔是10ms
以上這個理論反正我是沒有驗證過

Exemple 1 ------question:------
console.log("start");

const interval = setInterval(() => {  
console.log("setInterval");
}, 0);

setTimeout(() => {  
console.log("setTimeout 1");
Promise.resolve()
    .then(() => {
        console.log("promise 3");
    })
    .then(() => {
        console.log("promise 4");
    })
    .then(() => {
        setTimeout(() => {
        console.log("setTimeout 2");
        Promise.resolve()
            .then(() => {
                console.log("promise 5");
            })
            .then(() => {
                console.log("promise 6");
            })
            .then(() => {
                clearInterval(interval);
            });
        }, 0);
    });
}, 0);

Promise.resolve()
    .then(() => {  
        console.log("promise 1");
    })
    .then(() => {
        console.log("promise 2");
    });
    
------非chrome result:------
    
start
promise 1
promise 2
setInterval
setTimeout 1
promise 3
promise 4
setInterval
setTimeout 2
promise 5
promise 6
------node.js result------
start
promise 1
promise 2
setInterval
setTimeout 1
promise 3
promise 4
setInterval
setTimeout 2
setInterval
promise 5
promise 6
------windows/mac chrome result:------
start
promise 1
promise 2
setInterval
setTimeout 1
promise 3
promise 4
setInterval
setInterval
setTimeout 2
promise 5
promise 6

在windows chrome里setTimeout 2上方會出現連續兩個setInterval,有些奇怪,在mac的chrome和windows的firefox都是正常的輸出(發生錯誤的window chrome版本號為:Version 65.0.3325.181 (Official Build) (64-bit))

經過更多次測試,關于上述結論做如下更正:
windows/mac chrome 運行這段代碼有時會出現雙setInterval情況,而另一些時候則和非chrome瀏覽器環境運行無異。這種情況筆者暫時還沒有找到準確的答案。

------windows chrome exemple:------
console.log("start");

var nerdPointer;
function nerdFunc(){
    console.log("setInterval");
    nerdPointer = setTimeout(nerdFunc,0);
}
setTimeout(nerdFunc,0);

setTimeout(() => {  
console.log("setTimeout 1");
Promise.resolve()
    .then(() => {
        console.log("promise 3");
    })
    .then(() => {
        console.log("promise 4");
    })
    .then(() => {
        setTimeout(() => {
        console.log("setTimeout 2");
        Promise.resolve()
            .then(() => {
                console.log("promise 5");
            })
            .then(() => {
                console.log("promise 6");
            })
            .then(() => {
                clearInterval(nerdPointer);
            });
        }, 0);
    });
}, 0);

Promise.resolve()
    .then(() => {  
        console.log("promise 1")
    })
    .then(() => {
        console.log("promise 2")
    });

windows chrome下跑上面這段代碼并不會出錯

Exemple 2 ------question:------
function expendTime(k){
    console.log((new Date()).getTime());
    while(k < 1000){
        for(var j = 2; j < k; j++){
            if(k%j == 0){
                break;
            }
            if(j == k-1){
                console.log(k)
            }
        }
        k++;
    }
    console.log((new Date()).getTime());
    clearInterval(t);
}

var t = setInterval(expendTime,15,3);
------result:------

結果:只進行了一次expendTime()計算

mac 17對于expendTime()的運行事件大概在30ms朝上,setInterval()設定的間隔是15ms,所以在expendTime()沒有執行完畢的時候并沒有再添加一個expendTime()task queue中(函數結尾setInterval()被清除),所以結果才只進行了一次expendTime()的計算

Example 3

Example 2中的代碼做如下修改,再次進行測試

------question:------
function expendTime(k){
    console.log((new Date()).getTime());
    while(k < 10000){
        for(var j = 2; j < k; j++){
            if(k%j == 0){
                break;
            }
            if(j == k-1){
                console.log(k)
            }
        }
        k++;
    }
    console.log((new Date()).getTime());
}

var t = setInterval(expendTime,15,3);
setTimeout(function (){clearInterval(t);},30);
------chrome result:------

輸出了兩次后被停止

------非chrome result:------

輸出一次后停止,證明在大多數瀏覽器上,Exemple 2中的結論是正確的

------conclusion:------

又是在chrome上出現了不合理的詭異的行為。和標準中event loop的理論相悖

Example 4 ------question:------
function fn1() {
    for (var i = 0; i < 4; i++) {
        var tc = setTimeout(function(i) {
            console.log(i);
            clearTimeout(tc)
        }, 10, i);
    }
}

function fn2() {
    for (var i = 0; i < 4; i++) {
        var tc = setInterval(function(i, tc) {
            console.log(i);
            clearInterval(tc)
        }, 10, i, tc);
    }
}
fn1();
fn2();
------answer:------

這題考察了對閉包和定時器另外還有js執行順序的理解。
先來說說fn1,如果把clearTimeout去掉,相信大家一定很熟悉,都會說10ms延遲后會依次輸出0,1,2,3。
但是,請注意這里加了個clearTimeout,如果你去控制臺實驗的話會發現只輸出了0,1,2,那3呢?
先別急,請聽我慢慢道來:
請注意:這個tc是定義在閉包外面的,也就是說tc并沒有被閉包保存,所以這里的tc指的是最后一個循環留下來的tc,所以最后一個3被清除了,沒有輸出。

再來看看fn2,可以發現區別就是把setTimeout改為了setInterval,同時把定時器也傳到了閉包里。
那么結果又會有什么不同呢?如果親自去實驗的同學就會發現輸出0,1,2,3,3,3...。
什么鬼?為毛最后一個定時器沒被刪除。說實話,我在這里也想了很久,為何最后一個定時器沒被刪除。后來我為了調試方便把i<4改為了i<2并把觸發時間改為3s,在瀏覽器中單步調試,發現3s后第一次觸發回調函數執行的時候tc的值是undefined第二次觸發的時候有值了。這個時候我頓悟,這和程序的執行順序有關。我們知道js正常情況下是從上到下,從右到左執行的。
所以這里每次循環先設置定時器,然后把定時器的返回值賦值給tc。在第一次循環的時候tc并沒有被賦值,所以是undefined,在第二次循環的時候,定時器其實清理的是上一個循環的定時器。所以導致每次循環都是清理上一次的定時器,而最后一次循環的定時器沒被清理,導致一直輸出3。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/107683.html

相關文章

  • node核心特性理解

    摘要:概述本文主要介紹了我對的一些核心特性的理解,包括架構特點機制核心模塊與簡單應用。在此期間,主線程繼續執行其他任務。延續了瀏覽器端單線程,只用一個主線程執行,不斷循環遍歷事件隊列,執行事件。 原文地址在我的博客,轉載請注明來源,謝謝! node是在前端領域經常看到的詞。node對于前端的重要性已經不言而喻,掌握node也是作為合格的前端工程師一項基本功了。知道node、知道后端的一些東西...

    huangjinnan 評論0 收藏0
  • 從瀏覽器多進程到JS單線程,JS運行機制最全面一次梳理

    摘要:如果看完本文后,還對進程線程傻傻分不清,不清楚瀏覽器多進程瀏覽器內核多線程單線程運行機制的區別。因此準備梳理這塊知識點,結合已有的認知,基于網上的大量參考資料,從瀏覽器多進程到單線程,將引擎的運行機制系統的梳理一遍。 前言 見解有限,如有描述不當之處,請幫忙及時指出,如有錯誤,會及時修正。 ----------超長文+多圖預警,需要花費不少時間。---------- 如果看完本文后,還...

    wanghui 評論0 收藏0
  • 徹底弄懂 JavaScript 執行機制

    摘要:關于這部分有嚴格的文字定義,但本文的目的是用最小的學習成本徹底弄懂執行機制,所以同步和異步任務分別進入不同的執行場所,同步的進入主線程,異步的進入并注冊函數。宏任務微任務第三輪事件循環宏任務執行結束,執行兩個微任務和。 不論你是javascript新手還是老鳥,不論是面試求職,還是日常開發工作,我們經常會遇到這樣的情況:給定的幾行代碼,我們需要知道其輸出內容和順序。 因為javascr...

    gyl_coder 評論0 收藏0
  • 這一次,徹底弄懂 JavaScript 執行機制

    摘要:事件完成,回調函數進入。主線程從讀取回調函數并執行。終于執行完了,終于從進入了主線程執行。遇到,立即執行。宏任務微任務第三輪事件循環宏任務執行結束,執行兩個微任務和。事件循環事件循環是實現異步的一種方法,也是的執行機制。 本文的目的就是要保證你徹底弄懂javascript的執行機制,如果讀完本文還不懂,可以揍我。不論你是javascript新手還是老鳥,不論是面試求職,還是日常開發工作...

    dreambei 評論0 收藏0
  • 瀏覽器知識

    摘要:瀏覽器的渲染進程是多線程的。異步請求線程在在連接后是通過瀏覽器新開一個線程請求將檢測到狀態變更時,如果設置有回調函數,異步線程就產生狀態變更事件,將這個回調再放入事件隊列中。 [TOC] 瀏覽器進程線程 區分線程和進程 **- 什么是進程** 狹義定義:進程是正在運行的程序的實例(an instance of a computer program that is being exe...

    Pluser 評論0 收藏0

發表評論

0條評論

nidaye

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<