成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

chrome下的Javascript的任務(wù)機(jī)制

nidaye / 1994人閱讀

摘要:在第一次循環(huán)的時(shí)候并沒有被賦值,所以是,在第二次循環(huán)的時(shí)候,定時(shí)器其實(shí)清理的是上一個(gè)循環(huán)的定時(shí)器。所以導(dǎo)致每次循環(huán)都是清理上一次的定時(shí)器,而最后一次循環(huán)的定時(shí)器沒被清理,導(dǎo)致一直輸出。

Javascript Evet Loop 模型

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

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上方會(huì)出現(xiàn)連續(xù)兩個(gè)setInterval,有些奇怪,在mac的chrome和windows的firefox都是正常的輸出(發(fā)生錯(cuò)誤的window chrome版本號(hào)為:Version 65.0.3325.181 (Official Build) (64-bit))

經(jīng)過更多次測(cè)試,關(guān)于上述結(jié)論做如下更正:
windows/mac chrome 運(yùn)行這段代碼有時(shí)會(huì)出現(xiàn)雙setInterval情況,而另一些時(shí)候則和非chrome瀏覽器環(huán)境運(yùn)行無(wú)異。這種情況筆者暫時(shí)還沒有找到準(zhǔn)確的答案。

------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下跑上面這段代碼并不會(huì)出錯(cuò)

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:------

結(jié)果:只進(jìn)行了一次expendTime()計(jì)算

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

Example 3

Example 2中的代碼做如下修改,再次進(jìn)行測(cè)試

------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:------

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

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

又是在chrome上出現(xiàn)了不合理的詭異的行為。和標(biāo)準(zhǔn)中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:------

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

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

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/107683.html

相關(guān)文章

  • node核心特性理解

    摘要:概述本文主要介紹了我對(duì)的一些核心特性的理解,包括架構(gòu)特點(diǎn)機(jī)制核心模塊與簡(jiǎn)單應(yīng)用。在此期間,主線程繼續(xù)執(zhí)行其他任務(wù)。延續(xù)了瀏覽器端單線程,只用一個(gè)主線程執(zhí)行,不斷循環(huán)遍歷事件隊(duì)列,執(zhí)行事件。 原文地址在我的博客,轉(zhuǎn)載請(qǐng)注明來源,謝謝! node是在前端領(lǐng)域經(jīng)??吹降脑~。node對(duì)于前端的重要性已經(jīng)不言而喻,掌握node也是作為合格的前端工程師一項(xiàng)基本功了。知道node、知道后端的一些東西...

    huangjinnan 評(píng)論0 收藏0
  • 從瀏覽器多進(jìn)程到JS單線程,JS運(yùn)行機(jī)制最全面一次梳理

    摘要:如果看完本文后,還對(duì)進(jìn)程線程傻傻分不清,不清楚瀏覽器多進(jìn)程瀏覽器內(nèi)核多線程單線程運(yùn)行機(jī)制的區(qū)別。因此準(zhǔn)備梳理這塊知識(shí)點(diǎn),結(jié)合已有的認(rèn)知,基于網(wǎng)上的大量參考資料,從瀏覽器多進(jìn)程到單線程,將引擎的運(yùn)行機(jī)制系統(tǒng)的梳理一遍。 前言 見解有限,如有描述不當(dāng)之處,請(qǐng)幫忙及時(shí)指出,如有錯(cuò)誤,會(huì)及時(shí)修正。 ----------超長(zhǎng)文+多圖預(yù)警,需要花費(fèi)不少時(shí)間。---------- 如果看完本文后,還...

    wanghui 評(píng)論0 收藏0
  • 徹底弄懂 JavaScript 執(zhí)行機(jī)制

    摘要:關(guān)于這部分有嚴(yán)格的文字定義,但本文的目的是用最小的學(xué)習(xí)成本徹底弄懂執(zhí)行機(jī)制,所以同步和異步任務(wù)分別進(jìn)入不同的執(zhí)行場(chǎng)所,同步的進(jìn)入主線程,異步的進(jìn)入并注冊(cè)函數(shù)。宏任務(wù)微任務(wù)第三輪事件循環(huán)宏任務(wù)執(zhí)行結(jié)束,執(zhí)行兩個(gè)微任務(wù)和。 不論你是javascript新手還是老鳥,不論是面試求職,還是日常開發(fā)工作,我們經(jīng)常會(huì)遇到這樣的情況:給定的幾行代碼,我們需要知道其輸出內(nèi)容和順序。 因?yàn)閖avascr...

    gyl_coder 評(píng)論0 收藏0
  • 這一次,徹底弄懂 JavaScript 執(zhí)行機(jī)制

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

    dreambei 評(píng)論0 收藏0
  • 瀏覽器知識(shí)

    摘要:瀏覽器的渲染進(jìn)程是多線程的。異步請(qǐng)求線程在在連接后是通過瀏覽器新開一個(gè)線程請(qǐng)求將檢測(cè)到狀態(tài)變更時(shí),如果設(shè)置有回調(diào)函數(shù),異步線程就產(chǎn)生狀態(tài)變更事件,將這個(gè)回調(diào)再放入事件隊(duì)列中。 [TOC] 瀏覽器進(jìn)程線程 區(qū)分線程和進(jìn)程 **- 什么是進(jìn)程** 狹義定義:進(jìn)程是正在運(yùn)行的程序的實(shí)例(an instance of a computer program that is being exe...

    Pluser 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<