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

資訊專(zhuān)欄INFORMATION COLUMN

由setTimeout深入JavaScript執(zhí)行環(huán)境的異步機(jī)制

codeGoogle / 1422人閱讀

摘要:圖片轉(zhuǎn)引自的演講和兩個(gè)定時(shí)器中回調(diào)的執(zhí)行邏輯便是典型的機(jī)制。異步編程關(guān)于異步編程我的理解是,在執(zhí)行環(huán)境所提供的異步機(jī)制之上,在應(yīng)用編碼層面上實(shí)現(xiàn)整體流程控制的異步風(fēng)格。

問(wèn)題背景

在一次開(kāi)發(fā)任務(wù)中,需要實(shí)現(xiàn)如下一個(gè)餅狀圖動(dòng)畫(huà),基于canvas進(jìn)行繪圖,但由于對(duì)于JS運(yùn)行環(huán)境中異步機(jī)制的不了解,所以遇到了一個(gè)棘手的問(wèn)題,始終無(wú)法解決,之后在與同事交流之后才恍然大悟。問(wèn)題的根節(jié)在于經(jīng)典的JS定時(shí)器異步問(wèn)題,所以在解決問(wèn)題之后,又通過(guò)了大量的資料閱讀擴(kuò)展和一段時(shí)間的實(shí)戰(zhàn)總結(jié),現(xiàn)在對(duì)JS運(yùn)行環(huán)境中異步機(jī)制做一個(gè)較為深入的分析。

上圖中為最終想要實(shí)現(xiàn)的效果,使得各扇形部分可以同時(shí)畫(huà)出并閉合圓形。點(diǎn)擊此處查看代碼清單。之前遇到的問(wèn)題是沒(méi)有將myLoop作為一個(gè)函數(shù)抽離出來(lái),而將其中的所有邏輯,包括定時(shí)器都寫(xiě)在了for循環(huán)中,這樣雖然扇形角度、哨兵變量等的計(jì)算均正確,但圓形始終無(wú)法閉合,很是郁悶。這里我只是想借此問(wèn)題來(lái)引入JS運(yùn)行環(huán)境中對(duì)于異步機(jī)制理解的重要性,大可不必關(guān)心canvas畫(huà)圖的實(shí)現(xiàn)過(guò)程,讓大家明白對(duì)異步的理解會(huì)牽扯到業(yè)務(wù)邏輯執(zhí)行的準(zhǔn)確性,并非只是用于浮于紙面的面試題之上。至于為什么將定時(shí)器的邏輯放在一個(gè)函數(shù)中就執(zhí)行正常,而直接寫(xiě)入for循環(huán)就無(wú)法達(dá)到預(yù)期,看過(guò)下文的詳細(xì)分析后,這個(gè)問(wèn)題便會(huì)迎刃而解。

深入異步

關(guān)于異步的深入,這里基于現(xiàn)有的知識(shí)水平做盡可能詳盡準(zhǔn)確的分析。大家可以從一篇博客進(jìn)一步了解牛人之間對(duì)于異步理解的爭(zhēng)論。一位是技術(shù)博客紅人阮一峰老師,一位是國(guó)內(nèi)Node技術(shù)的開(kāi)山鼻祖樸靈老師,都是我持續(xù)關(guān)注的兩位偶像。事情發(fā)生的比較早了,這里只給出一個(gè)文章鏈接,其中在阮老師的博文中附帶了大量樸靈老師的批注,讀過(guò)之后定會(huì)受益匪淺,也會(huì)激發(fā)出你對(duì)技術(shù)外的一些思考。

同步與異步

首先來(lái)說(shuō)明同步與異步兩個(gè)概念。

f1()
f2()

對(duì)于JavaScript語(yǔ)言的執(zhí)行方式,執(zhí)行環(huán)境會(huì)支持兩種模式,一種是同步執(zhí)行,一種是異步執(zhí)行。如上面兩個(gè)方法,同步執(zhí)行就是調(diào)用f1之后,等待返回結(jié)果,再執(zhí)行f2。異步是調(diào)用f1后,通過(guò)一系列其他的操作才可以得到預(yù)期的結(jié)果,比如網(wǎng)絡(luò)IO、磁盤(pán)IO等,在線程執(zhí)行這些其他操作的同時(shí),程序還可以往下執(zhí)行,繼續(xù)調(diào)用f2,不用等待f1的結(jié)果返回再執(zhí)行f2。

我們知道,大部分的腳本和編程語(yǔ)言都是同步編程,開(kāi)發(fā)者對(duì)于同步編程的執(zhí)行邏輯也比較容易理解。那么為什么對(duì)于JS的執(zhí)行要經(jīng)常用到異步編程,這應(yīng)該要追溯到最初JS適用的宿主環(huán)境--瀏覽器。

由于用于瀏覽器,所以操作DOM的JS只能使用單線程,否則無(wú)法保證DOM操作的安全性(比如一個(gè)線程將另一個(gè)線程正在使用的某個(gè)DOM刪掉)。又因?yàn)槭褂脝尉€程,同步執(zhí)行代碼的話,如果遇到耗時(shí)較長(zhǎng)的操作,那么瀏覽器將會(huì)長(zhǎng)時(shí)間失去響應(yīng),用戶體驗(yàn)及其不好。但如果將耗時(shí)較長(zhǎng)的任務(wù),比如ajax請(qǐng)求異步執(zhí)行,那么客戶端的渲染便不會(huì)受到耗時(shí)任務(wù)的阻塞。

對(duì)于服務(wù)器端,JS異步執(zhí)行更為重要,因?yàn)閳?zhí)行環(huán)境是單線程的,如果同步執(zhí)行所有并發(fā)請(qǐng)求,那么對(duì)于客戶端的響應(yīng)將會(huì)極其遲鈍,服務(wù)器性能急劇下降,這時(shí)必須使用異步模式來(lái)處理大量并發(fā)請(qǐng)求,不像Java、PHP等語(yǔ)言是通過(guò)多線程來(lái)解決并發(fā)問(wèn)題。這點(diǎn)在現(xiàn)在高并發(fā)司空見(jiàn)慣的網(wǎng)絡(luò)環(huán)境中,反而成為了JS的優(yōu)勢(shì),使得Node在短時(shí)間內(nèi)進(jìn)入主流視野,成為DIRT應(yīng)用1的最佳解決方案。

實(shí)現(xiàn)異步的機(jī)制

在說(shuō)實(shí)現(xiàn)異步的機(jī)制之前,首先需要搞清楚兩個(gè)概念,分別是JavaScript的執(zhí)行引擎執(zhí)行環(huán)境。我們常說(shuō)Google的V8虛擬機(jī)便是JavaScript的執(zhí)行引擎,除此之外Safari的JavaScript Core、FireFox的SpiderMonckey都屬于Engine。而上述的瀏覽器和Node等便屬于JavaScript的執(zhí)行環(huán)境,是Runtime。前者Engine是去實(shí)現(xiàn)ECMAScript標(biāo)準(zhǔn),后者Runtime是去實(shí)現(xiàn)異步的具體機(jī)制。所以我們今天講的JS異步機(jī)制都是在說(shuō)JS執(zhí)行環(huán)境的異步機(jī)制,與V8這樣的執(zhí)行引擎并無(wú)關(guān)系,主要是由各大瀏覽器廠商去做實(shí)現(xiàn)。

關(guān)于實(shí)現(xiàn)異步的方式,有我們接下來(lái)要詳細(xì)介紹的Event Loop,還有輪詢(xún)、事件等。所謂輪詢(xún),就是你在收銀臺(tái)付款之后,不停的問(wèn)服務(wù)員你的飯菜做好了嗎。所謂事件,就是你在付款之后,不用不停的問(wèn)服務(wù)員,服務(wù)員在做好飯菜之后會(huì)主動(dòng)告訴你。而大部分的執(zhí)行環(huán)境都是通過(guò)Event Loop去實(shí)現(xiàn)異步機(jī)制,所以下面重點(diǎn)來(lái)講解Event Loop。

Event Loop

Event Loop的實(shí)現(xiàn)邏輯如下圖。每當(dāng)程序啟動(dòng)后,內(nèi)存會(huì)被分為堆(heap)和棧(stack)兩部分,其中棧中便是主線程的執(zhí)行邏輯所需內(nèi)存,我們根據(jù)這塊內(nèi)存的特殊作用,抽象的將其叫做執(zhí)行棧。在棧中的代碼會(huì)調(diào)用各種WebAPI,比如對(duì)DOM的操作,ajax請(qǐng)求,創(chuàng)建定時(shí)器等。這些操作會(huì)產(chǎn)生一些事件,而事件又會(huì)關(guān)聯(lián)相應(yīng)的handle(也就是注冊(cè)時(shí)的callback),將需要執(zhí)行的handle按照隊(duì)列的結(jié)構(gòu)放入callback queue(event queue)中。當(dāng)執(zhí)行棧中的代碼執(zhí)行完畢后,主線程會(huì)讀取callback queue,依次執(zhí)行其中的回調(diào)函數(shù),然后進(jìn)入下一輪的事件循環(huán),執(zhí)行清空新產(chǎn)生的事件回調(diào)函數(shù)。由此可見(jiàn),在執(zhí)行棧中的代碼總是在callback queue之前執(zhí)行。

圖片轉(zhuǎn)引自Philip Roberts的演講《Help, I"m stuck in an event-loop》

setTimeout()和setInterval()兩個(gè)定時(shí)器中回調(diào)的執(zhí)行邏輯便是典型的Event Loop機(jī)制。相似的,程序在跑完執(zhí)行棧中的代碼后,事件循環(huán)會(huì)不停的檢查系統(tǒng)時(shí)間是否到達(dá)預(yù)設(shè)的時(shí)間點(diǎn),每當(dāng)?shù)竭_(dá)預(yù)設(shè)的時(shí)間點(diǎn)時(shí),就會(huì)產(chǎn)生一個(gè)timeout事件,并將其放入callback queue,等待下輪Event loop執(zhí)行。但在實(shí)際應(yīng)用中,有可能執(zhí)行棧中的代碼耗時(shí)過(guò)長(zhǎng),這樣在執(zhí)行完執(zhí)行棧中的代碼后,再去執(zhí)行callback queue中由setTimeout()產(chǎn)生的回調(diào)時(shí)就不能保證在預(yù)期的時(shí)間點(diǎn)執(zhí)行,所以JS中的定時(shí)器并不總能保證其精準(zhǔn)性。而在詳細(xì)了解其特性原理后,我們可以在編程應(yīng)用層面做一些優(yōu)化,盡量使定時(shí)器中回調(diào)函數(shù)的執(zhí)行時(shí)間點(diǎn)與我們預(yù)期保持一致。由于setTimeout()與setInterval()在本質(zhì)上是一致的,所以在下面的實(shí)例分析一節(jié)中我們將會(huì)以setTimeout()來(lái)做關(guān)于異步機(jī)制的分析。

異步編程

關(guān)于異步編程我的理解是,在JS執(zhí)行環(huán)境所提供的異步機(jī)制之上,在應(yīng)用編碼層面上實(shí)現(xiàn)整體流程控制的異步風(fēng)格。具體地,我們可以用類(lèi)似setTimeout()中的回調(diào)函數(shù)的形式進(jìn)行異步編程,或者用類(lèi)似事件驅(qū)動(dòng)的發(fā)布/訂閱模式,或者用ES6為我們提供的異步編程的統(tǒng)一接口Promise實(shí)現(xiàn),再或者可以嘗試最新最酷的ES7中Async/Await方案,還有一些像Node社區(qū)提供的異步流控庫(kù)Step等。這里只是為大家明確異步編程這個(gè)概念范疇,具體用法不再深入。

實(shí)例分析

這一節(jié)中我將會(huì)舉出多例來(lái)分析,請(qǐng)大家結(jié)合上述理論細(xì)細(xì)體會(huì)JS中的同步與異步。首先我們從一個(gè)經(jīng)典的JS異步面試題開(kāi)始,然后逐漸深入。

for (var i = 0; i < 5; i++) {
    setTimeout(function() {
        console.log(new Date, i);
    }, 1000);
}
 
console.log(new Date, i);

上述代碼片段的運(yùn)行結(jié)果應(yīng)該是,先立即輸出一個(gè)5,然后在1秒以后同時(shí)輸出五個(gè)5。程序開(kāi)始執(zhí)行后,首先執(zhí)行執(zhí)行棧中的同步代碼,幾乎同時(shí)創(chuàng)建了5個(gè)定時(shí)器,然后繼續(xù)執(zhí)行第7行的同步代碼。這樣,首先在控制臺(tái)輸出一個(gè)5,然后在1s以后,5個(gè)定時(shí)器同時(shí)產(chǎn)生5個(gè)timeout事件放入callback queue,Event loop依次執(zhí)行隊(duì)列中的回調(diào)函數(shù),這里因?yàn)殚]包的特性,每一個(gè)定時(shí)器的回調(diào)都與其定義上下文,for循環(huán)中的i變量做了綁定,而i的值已變?yōu)?,所以同時(shí)輸出五個(gè)5。

如果現(xiàn)在提出一個(gè)新需求,要求程序運(yùn)行后,先立即輸出一個(gè)5,然后在1s以后同時(shí)輸出0,1,2,3,4,如何改造上述代碼?

//方法一
for (var i = 0; i < 5; i++) {
    (function(j) {  
        setTimeout(function() {
            console.log(new Date, j);
        }, 1000);
    })(i);
}
 
console.log(new Date, i);

//方法二
function output (i) {
    setTimeout(function() {
        console.log(new Date, i);
    }, 1000);
};
 
for (var i = 0; i < 5; i++) {
    output(i);  
}
 
console.log(new Date, i);

上面給出的兩種方法其實(shí)都是一種思路,都是利用JS中,函數(shù)作用域作為一個(gè)獨(dú)立的作用域,來(lái)保存一個(gè)局部的上下文環(huán)境,并通過(guò)閉包的特性使其與setTimeout中的回調(diào)函數(shù)做綁定。只不過(guò)第一種方法是利用IIFE2來(lái)實(shí)現(xiàn),第二種方法是通過(guò)定義一個(gè)函數(shù),再來(lái)逐個(gè)調(diào)用實(shí)現(xiàn)??吹竭@里,應(yīng)該想到對(duì)于篇首問(wèn)題背景一節(jié)中所提到的問(wèn)題便與此處如出一轍。

接下來(lái)我們進(jìn)一步深入,提出一個(gè)新的需求。如何在代碼執(zhí)行時(shí),立即輸出 0,之后每隔1s依次輸出 1,2,3,4,循環(huán)結(jié)束后在大概第5秒的時(shí)候輸出5?

因?yàn)榍斑吤扛?s輸出的0,1,2,3,4是五個(gè)定時(shí)器輸出的,也就是五個(gè)異步操作,那么我們是不是可以把這次的需求抽象為:在一系列異步操作完成(每次循環(huán)都產(chǎn)生了 1 個(gè)異步操作)之后,再做其他的事情?,F(xiàn)在熟悉ES6的同學(xué)應(yīng)該想到了Promise。

const tasks = []; // 這里存放異步操作的 Promise
const output = (i) => new Promise((resolve) => {
    setTimeout(() => {
        console.log(new Date, i);
        resolve();
    }, 1000 * i);
});
 
// 生成全部的異步操作
for (var i = 0; i < 5; i++) {
    tasks.push(output(i));
}
 
// 異步操作完成之后,輸出最后的 i
Promise.all(tasks).then(() => {
    setTimeout(() => {
        console.log(new Date, i);
    }, 1000);
});

如果你熟悉ES7中的Async/Await,那么也可以嘗試用這種方案解決。

// 模擬其他語(yǔ)言中的 sleep,實(shí)際上可以是任何異步操作
const sleep = (timeountMS) => new Promise((resolve) => {
    setTimeout(resolve, timeountMS);
});
 
(async () => {  // 聲明即執(zhí)行的 async 函數(shù)表達(dá)式
    for (var i = 0; i < 5; i++) {
        await sleep(1000);
        console.log(new Date, i);
    }
 
    await sleep(1000);
    console.log(new Date, i);
})();

這里需要著重注意的是瀏覽器對(duì)Async/Await標(biāo)準(zhǔn)的支持,如果你的瀏覽器不在以下所支持版本當(dāng)中,那么可以升級(jí)瀏覽器或使用babel轉(zhuǎn)譯處理。

能把上邊這一系列的實(shí)例理解到位,相信對(duì)JS中異步的這個(gè)概念會(huì)一些新的體會(huì)。下面這個(gè)實(shí)例會(huì)更加細(xì)化的考察一下異步代碼中回調(diào)的執(zhí)行時(shí)機(jī)。

let a = new Promise(
  function(resolve, reject) {
    console.log(1)
    setTimeout(() => console.log(2), 0)
    console.log(3)
    console.log(4)
    resolve(true)
  }
)
a.then(v => {
  console.log(8)
})
 
let b = new Promise(
  function() {
    console.log(5)
    setTimeout(() => console.log(6), 0)
  }
)
 
console.log(7)

這里首先來(lái)明確一點(diǎn),Promise是ES6中為異步編程所提供的一套API標(biāo)準(zhǔn),其本身是同步的。所以我們?cè)趎ew一個(gè)Promise對(duì)象的時(shí)候,其所執(zhí)行的構(gòu)造器中的邏輯是同步的。由此得知,上述代碼片段先從上到下依次執(zhí)行同步代碼,輸出1,3,4,5,7。然后是先執(zhí)行then中的異步代碼還是先執(zhí)行setTimeout中的回調(diào)代碼?這里需要記住前者要比后者先進(jìn)入執(zhí)行棧執(zhí)行,所以后邊輸出8,2,6。這是因?yàn)榱⒓磖esolved的Promise是在本輪事件循環(huán)的末尾執(zhí)行,類(lèi)似于node中的process.nextTick方法,它可以在當(dāng)前"執(zhí)行棧"的尾部,下一次Event Loop(主線程讀取"任務(wù)隊(duì)列")之前,觸發(fā)回調(diào)函數(shù)。setTimeout(fn, 0)則是在當(dāng)前"任務(wù)隊(duì)列"的尾部添加事件,也就是說(shuō),它指定的任務(wù)總是在下一輪次Event Loop時(shí)執(zhí)行,這與node中的setImmediate方法很像。

最后我們來(lái)說(shuō)一個(gè)關(guān)于setInterval優(yōu)化的例子。我們知道setTimeout中的回調(diào)觸發(fā)是不準(zhǔn)確的,主要原因是由于在需要執(zhí)行回調(diào)時(shí),可能執(zhí)行棧中的代碼還沒(méi)有執(zhí)行完,無(wú)法將CPU資源及時(shí)的調(diào)度給callback queue中的回調(diào)執(zhí)行。而setInterval也會(huì)存在一些問(wèn)題,比如時(shí)間間隔可能會(huì)跳過(guò),
時(shí)間間隔可能小于定時(shí)器設(shè)定的時(shí)間。發(fā)生這類(lèi)情況其實(shí)也是由于其他的程序占用長(zhǎng)時(shí)間的CPU時(shí)間片引起,以下面代碼片段為例:

function click() { 
    // code block1... 
    setInterval(function() { 
        // process ... 
    }, 200); 
    // code block2 ...
}

如果process中的代碼執(zhí)行時(shí)間過(guò)長(zhǎng),占用了超過(guò)400ms,那么此時(shí)JS執(zhí)行環(huán)境就會(huì)跳過(guò)中間一次時(shí)間間隔,因?yàn)閏allback queue中只允許有一份process代碼存在,所以也會(huì)產(chǎn)生觸發(fā)時(shí)機(jī)不精準(zhǔn)的情況。

為了避免這種情況的出現(xiàn),我們可以利用遞歸的方式進(jìn)行優(yōu)化處理,以下提供兩種寫(xiě)法,但是建議使用第一種寫(xiě)法。因?yàn)榈诙N寫(xiě)法中,在嚴(yán)格模式下,第5版 ECMAScript (ES5) 禁止使用 arguments.callee()。當(dāng)一個(gè)函數(shù)必須調(diào)用自身的時(shí)候, 避免使用 arguments.callee(), 通過(guò)要么給函數(shù)表達(dá)式一個(gè)名字,要么使用一個(gè)函數(shù)聲明參見(jiàn)MDN解釋

    // 寫(xiě)法一
    setTimeout(function bar (){ 
        // processing
        foo = setTimeout(bar, 1000); 
    }, 1000);
    
    // 寫(xiě)法二
    setTimeout(function(){ 
        // processing 
        foo = setTimeout(arguments.callee, interval); 
    }, interval);
    
    clearTimeout(foo) // 停止循環(huán)
  • Data-Intensive Real-Time 這里指數(shù)據(jù)密集、實(shí)時(shí)交互類(lèi)應(yīng)用。 ?

  • Immediately Invoked Function Expression:聲明即執(zhí)行的函數(shù)表達(dá)式。 ?

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

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

    相關(guān)文章

    • JavaScript執(zhí)行順序分析

      摘要:每個(gè)線程的任務(wù)執(zhí)行順序都是先進(jìn)先出在運(yùn)行的環(huán)境中,有一個(gè)負(fù)責(zé)程序本身的運(yùn)行,作為主線程另一個(gè)負(fù)責(zé)主線程與其他線程的通信,被稱(chēng)為線程。主線程繼續(xù)執(zhí)行我是第一主線程執(zhí)行完畢,從線程讀取回調(diào)函數(shù)。 前言 上星期面試被問(wèn)到了事件執(zhí)行順序的問(wèn)題,想起來(lái)之前看《深入淺出Node.js》時(shí)看到這一章就忽略了,這次來(lái)分析一下JavaScript的事件執(zhí)行順序。廢話少說(shuō),正題開(kāi)始。 單線程JavaScr...

      chnmagnus 評(píng)論0 收藏0
    • 【轉(zhuǎn)】深入理解JS單線程機(jī)制【原文作者:MasterYao】

      摘要:的單線程,與它的用途有關(guān)。只要指定過(guò)回調(diào)函數(shù),這些事件發(fā)生時(shí)就會(huì)進(jìn)入任務(wù)隊(duì)列,等待主線程讀取。四主線程從任務(wù)隊(duì)列中讀取事件,這個(gè)過(guò)程是循環(huán)不斷的,所以整個(gè)的這種運(yùn)行機(jī)制又稱(chēng)為事件循環(huán)。令人困惑的是,文檔中稱(chēng),指定的回調(diào)函數(shù),總是排在前面。 原文:http://www.cnblogs.com/Master... 一、為什么JavaScript是單線程? JavaScript語(yǔ)言的一大特點(diǎn)...

      LittleLiByte 評(píng)論0 收藏0
    • 深入淺出JavaScript運(yùn)行機(jī)制

      摘要:主線程從任務(wù)隊(duì)列中讀取事件,這個(gè)過(guò)程是循環(huán)不斷的,所以整個(gè)的這種運(yùn)行機(jī)制又稱(chēng)為事件循環(huán)。上面也提到,在到達(dá)指定時(shí)間時(shí),定時(shí)器就會(huì)將相應(yīng)回調(diào)函數(shù)插入任務(wù)隊(duì)列尾部。這就是定時(shí)器功能。關(guān)于定時(shí)器的重要補(bǔ)充定時(shí)器包括與兩個(gè)方法。 一、引子 本文介紹JavaScript運(yùn)行機(jī)制,這一部分比較抽象,我們先從一道面試題入手: console.log(1); setTimeout(function()...

      mochixuan 評(píng)論0 收藏0
    • 深入淺出JavaScript運(yùn)行機(jī)制

      摘要:主線程從任務(wù)隊(duì)列中讀取事件,這個(gè)過(guò)程是循環(huán)不斷的,所以整個(gè)的這種運(yùn)行機(jī)制又稱(chēng)為事件循環(huán)。上面也提到,在到達(dá)指定時(shí)間時(shí),定時(shí)器就會(huì)將相應(yīng)回調(diào)函數(shù)插入任務(wù)隊(duì)列尾部。這就是定時(shí)器功能。關(guān)于定時(shí)器的重要補(bǔ)充定時(shí)器包括與兩個(gè)方法。 一、引子 本文介紹JavaScript運(yùn)行機(jī)制,這一部分比較抽象,我們先從一道面試題入手: console.log(1); setTimeout(function()...

      魏明 評(píng)論0 收藏0
    • 深入淺出JavaScript運(yùn)行機(jī)制

      摘要:主線程從任務(wù)隊(duì)列中讀取事件,這個(gè)過(guò)程是循環(huán)不斷的,所以整個(gè)的這種運(yùn)行機(jī)制又稱(chēng)為事件循環(huán)。上面也提到,在到達(dá)指定時(shí)間時(shí),定時(shí)器就會(huì)將相應(yīng)回調(diào)函數(shù)插入任務(wù)隊(duì)列尾部。這就是定時(shí)器功能。關(guān)于定時(shí)器的重要補(bǔ)充定時(shí)器包括與兩個(gè)方法。 一、引子 本文介紹JavaScript運(yùn)行機(jī)制,這一部分比較抽象,我們先從一道面試題入手: console.log(1); setTimeout(function()...

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

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

    0條評(píng)論

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