摘要:定時(shí)器功能主要由和這兩個(gè)函數(shù)來完成,它們的內(nèi)部運(yùn)行機(jī)制完全一樣,區(qū)別在于前者指定的代碼是一次性執(zhí)行,后者則為反復(fù)執(zhí)行。也就是說當(dāng)引擎線程處于運(yùn)行狀態(tài)時(shí),渲染線程將處于凍結(jié)狀態(tài)。
同步編程,就是計(jì)算機(jī)一行一行按順序依次執(zhí)行代碼,當(dāng)前代碼任務(wù)耗時(shí)執(zhí)行會(huì)阻塞后續(xù)代碼的執(zhí)行。同步編程,即是一種典型的請(qǐng)求-響應(yīng)模型,當(dāng)請(qǐng)求調(diào)用一個(gè)函數(shù)或方法后,需等待其響應(yīng)返回,然后執(zhí)行后續(xù)代碼。假如代碼執(zhí)行到一個(gè)死循環(huán),那么代碼就一直卡在那里,永遠(yuǎn)不往下繼續(xù)執(zhí)行,線程同步也有這樣的缺點(diǎn),只能單線程從上往下逐步執(zhí)行,耗時(shí)較長(zhǎng),在等待的過程中,不能做任何其他的事情,此時(shí)頁(yè)面的交互,滾動(dòng)等任何操作也都會(huì)被阻塞,這顯然是及其不友好,不可接受的。
異步編程,不同于同步編程的請(qǐng)求-響應(yīng)模式,其是一種事件驅(qū)動(dòng)編程,請(qǐng)求調(diào)用函數(shù)或方法后,無需立即等待響應(yīng),可以繼續(xù)執(zhí)行其他任務(wù),而之前任務(wù)響應(yīng)返回后可以通過狀態(tài)、通知和回調(diào)來通知調(diào)用者。
Javascript實(shí)現(xiàn)異步
JavaScript執(zhí)行異步任務(wù)時(shí),不需要等待響應(yīng)返回,可以繼續(xù)執(zhí)行其他任務(wù),而在響應(yīng)返回時(shí),會(huì)得到通知,執(zhí)行回調(diào)或事件處理程序
1,首要要知道JavaScript語(yǔ)言是單線程的
JavaScript語(yǔ)言的一大特點(diǎn)就是單線程,也就是說,同一個(gè)時(shí)間只能做一件事。那么,為什么JavaScript不能有多個(gè)線程呢?這樣能提高效率啊。 JavaScript的單線程,與它的用途有關(guān)。作為瀏覽器腳本語(yǔ)言,JavaScript的主要用途是與用戶互動(dòng),以及操作DOM。這決定了它只能是單線程,否則會(huì)帶來很復(fù)雜的同步問題。比如,假定JavaScript同時(shí)有兩個(gè)線程,一個(gè)線程在某個(gè)DOM節(jié)點(diǎn)上添加內(nèi)容,另一個(gè)線程刪除了這個(gè)節(jié)點(diǎn),這時(shí)瀏覽器應(yīng)該以哪個(gè)線程為準(zhǔn)? 所以,為了避免復(fù)雜性,從一誕生,JavaScript就是單線程,這已經(jīng)成了這門語(yǔ)言的核心特征,將來也不會(huì)改變。 為了利用多核CPU的計(jì)算能力,HTML5提出Web Worker標(biāo)準(zhǔn),允許JavaScript腳本創(chuàng)建多個(gè)線程,但是子線程完全受主線程控制,且不得操作DOM。所以,這個(gè)新標(biāo)準(zhǔn)并沒有改變JavaScript單線程的本質(zhì)。
2,事件和回調(diào)函數(shù)
"任務(wù)隊(duì)列"是一個(gè)事件的隊(duì)列(也可以理解成消息的隊(duì)列),IO設(shè)備完成一項(xiàng)任務(wù),就在"任務(wù)隊(duì)列"中添加一個(gè)事件,表示相關(guān)的異步任務(wù)可以進(jìn)入"執(zhí)行棧"了。主線程讀取"任務(wù)隊(duì)列",就是讀取里面有哪些事件。 "任務(wù)隊(duì)列"中的事件,除了IO設(shè)備的事件以外,還包括一些用戶產(chǎn)生的事件(比如鼠標(biāo)點(diǎn)擊、頁(yè)面滾動(dòng)等等)。只要指定過回調(diào)函數(shù),這些事件發(fā)生時(shí)就會(huì)進(jìn)入"任務(wù)隊(duì)列",等待主線程讀取。 所謂"回調(diào)函數(shù)"(callback),就是那些會(huì)被主線程掛起來的代碼。異步任務(wù)必須指定回調(diào)函數(shù),當(dāng)主線程開始執(zhí)行異步任務(wù),就是執(zhí)行對(duì)應(yīng)的回調(diào)函數(shù)。
3,事件循環(huán)
(1)所有同步任務(wù)都在主線程上執(zhí)行,形成一個(gè)執(zhí)行棧
(2)主線程之外,還存在一個(gè)"任務(wù)隊(duì)列"。只要異步任務(wù)有了運(yùn)行結(jié)果,就在"任務(wù)隊(duì)列"之中放置一個(gè)事件。
(3)一旦"執(zhí)行棧"中的所有同步任務(wù)執(zhí)行完畢,系統(tǒng)就會(huì)讀取"任務(wù)隊(duì)列",看看里面有哪些事件。那些對(duì)應(yīng)的異步任務(wù),于是結(jié)束等待狀態(tài),進(jìn)入執(zhí)行棧,開始執(zhí)行。
(4)主線程不斷重復(fù)上面的第三步。
4:常見的異步場(chǎng)景
1:http請(qǐng)求
2:DOM事件(事件綁定)
3:定時(shí)器 消息隊(duì)列中除了放置異步任務(wù)的事件,"任務(wù)隊(duì)列"還可以放置定時(shí)事件,即指定某些代碼在多少時(shí)間之后執(zhí)行。這叫做"定時(shí)器"(timer)功能,也就是定時(shí)執(zhí)行的代碼。 定時(shí)器功能主要由setTimeout()和setInterval()這兩個(gè)函數(shù)來完成,它們的內(nèi)部運(yùn)行機(jī)制完全一樣,區(qū)別在于前者指定的代碼是一次性執(zhí)行,后者則為反復(fù)執(zhí)行。
JavaScript線程和瀏覽器線程的關(guān)系
瀏覽器是多線程的
Javascript是單線程的 :javascript引擎線程是瀏覽器多個(gè)線程中的一個(gè),它本身是單線程的。瀏覽器還包括很多其他線程,如GUI渲染線程,瀏覽器事件觸發(fā)線程,Http請(qǐng)求線程等。
js可以操作DOM元素,進(jìn)而會(huì)影響到GUI的渲染結(jié)果,因此JS引擎線程與GUI渲染線程是互斥的。也就是說當(dāng)JS引擎線程處于運(yùn)行狀態(tài)時(shí),GUI渲染線程將處于凍結(jié)狀態(tài)。
Promise的簡(jiǎn)單分析
官方解釋 Promise 是異步編程的一種解決方案,比傳統(tǒng)的解決方案——回調(diào)函數(shù)和事件——更合理和更強(qiáng)大。它由社區(qū)最早提出和實(shí)現(xiàn),ES6 將其寫進(jìn)了語(yǔ)言標(biāo)準(zhǔn),統(tǒng)一了用法,原生提供了Promise對(duì)象。
new Promise(function(resolve,reject) { console.log("Pending") //此時(shí)的promise的狀態(tài)是正在執(zhí)行 Pending resolve(); //代表狀態(tài)變成了 ‘resolve’ 將執(zhí)行resolve的對(duì)應(yīng)函數(shù) //reject(); //代表狀態(tài)變成了 是 ‘reject’ 將執(zhí)行reject的對(duì)應(yīng)函數(shù) }).then(function() { //直接在實(shí)例后點(diǎn)then(); 分別對(duì)應(yīng)resolve 和reject函數(shù) console.log("resolve") }, function() { console.log("reject") }) //promise的狀態(tài)一旦發(fā)生改變 就不可逆
Promise實(shí)例生成以后,可以用then方法分別指定Resolved狀態(tài)和Rejected狀態(tài)的回調(diào)函數(shù)。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/90117.html
摘要:異步任務(wù)必須指定回調(diào)函數(shù),當(dāng)異步任務(wù)從任務(wù)隊(duì)列回到執(zhí)行棧,回調(diào)函數(shù)就會(huì)執(zhí)行。事件循環(huán)主線程從任務(wù)隊(duì)列中讀取事件,這個(gè)過程是循環(huán)不斷的,所以整個(gè)的這種運(yùn)行機(jī)制又稱為。事件循環(huán)事件循環(huán)是指主線程重復(fù)從消息隊(duì)列中取消息執(zhí)行的過程。 參考鏈接:這一次,徹底弄懂 JavaScript 執(zhí)行機(jī)制https://zhuanlan.zhihu.com/p/...從瀏覽器多進(jìn)程到JS單線程,JS運(yùn)行機(jī)制...
摘要:主線程從任務(wù)隊(duì)列中讀取事件,這個(gè)過程是循環(huán)不斷的,所以整個(gè)的這種運(yùn)行機(jī)制又稱為事件循環(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()...
摘要:主線程從任務(wù)隊(duì)列中讀取事件,這個(gè)過程是循環(huán)不斷的,所以整個(gè)的這種運(yùn)行機(jī)制又稱為事件循環(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()...
摘要:主線程從任務(wù)隊(duì)列中讀取事件,這個(gè)過程是循環(huán)不斷的,所以整個(gè)的這種運(yùn)行機(jī)制又稱為事件循環(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()...
摘要:主線程不斷重復(fù)上面的三步,此過程也就是常說的事件循環(huán)。所以主線程代碼執(zhí)行時(shí)間過長(zhǎng),會(huì)阻塞事件循環(huán)的執(zhí)行。參考資料這一次,徹底弄懂執(zhí)行機(jī)制任務(wù)隊(duì)列的順序機(jī)制事件循環(huán)搞懂異步事件輪詢與中的事件循環(huán) 1. 說明 讀過本文章后,您能知道: JavaScript代碼在瀏覽器中的執(zhí)行機(jī)制和事件循環(huán) 面試中經(jīng)常遇到的代碼輸出順序問題 首先通過一段代碼來驗(yàn)證你是否了解代碼輸出順序,如果你不知道輸出...
閱讀 2457·2019-08-30 15:53
閱讀 2572·2019-08-29 13:11
閱讀 2653·2019-08-29 12:45
閱讀 3486·2019-08-29 12:41
閱讀 2326·2019-08-26 10:14
閱讀 2154·2019-08-23 14:39
閱讀 2314·2019-08-23 12:38
閱讀 3378·2019-08-23 12:04