五月天青色头像情侣网名,国产亚洲av片在线观看18女人,黑人巨茎大战俄罗斯美女,扒下她的小内裤打屁股

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

大前端進(jìn)擊之路(二)|JavaScript異步編程

2021-01-04 13:27 作者:光耀三十洲  | 我要投稿

打工人!打工魂!前端才是人上人!此系列總結(jié)于大前端進(jìn)擊之路過(guò)程中的學(xué)習(xí),如果文章中有不對(duì)的地方,希望大家能進(jìn)行批評(píng)改正,互相進(jìn)步。

經(jīng)典面試題

我們先來(lái)看一道經(jīng)典的面試題,讓我們的小腦袋瓜子思考起來(lái)~如果你對(duì)這道題有清晰的思路并且了解背后的原因,那么請(qǐng)直接點(diǎn)贊評(píng)論加關(guān)注!?。。?!

JS采用單線程模式工作的原因

為了回答這個(gè)問題我們首先需要知道JS的執(zhí)行環(huán)境是單線程的,是因?yàn)镴S語(yǔ)言最早是運(yùn)行在瀏覽器端的語(yǔ)言,目的是為了實(shí)現(xiàn)頁(yè)面上的動(dòng)態(tài)交互。實(shí)現(xiàn)動(dòng)態(tài)交互的核心就是DOM操作,因此決定了JS必須是單線程模式工作。我們來(lái)假設(shè)一下如果JS是多線程一起工作的,其中一個(gè)線程修改了一個(gè)DOM元素,另外的一個(gè)線程同時(shí)又要?jiǎng)h除這個(gè)DOM元素,那么此時(shí)瀏覽器就懵逼了,無(wú)法明確以哪個(gè)工作線程為準(zhǔn)。所以為了避免線程同步的問題,JS就被設(shè)計(jì)成了單線程的工作模式。

注意,我們這里說(shuō)的單線程是JS的執(zhí)行環(huán)境是單線程,瀏覽器中是多線程的。

單線程的優(yōu)勢(shì)和弊端

采用單線程的工作模式可以節(jié)省內(nèi)存,節(jié)約上下文切換時(shí)間,沒有鎖的問題。但弊端也很明顯,如果中間有一個(gè)任務(wù)需要花費(fèi)大量的時(shí)間,那么后面的任務(wù)就需要等待這個(gè)任務(wù)完成后才能執(zhí)行,就會(huì)出現(xiàn)假死的情況,對(duì)用戶很不友好。為了解決這個(gè)問題JS給出了兩種執(zhí)行模式:同步模式(Synchronous)和異步模式(Asynchronous)

同步模式和異步模式

同步模式

同步模式其實(shí)很好理解,舉個(gè)栗子:

我們?nèi)绻凑胀侥J街竺娴脑?,首先先將鍋里裝上水,打開火開始燒水,等待水燒開,再將面、雞蛋、火腿腸等材料拿出,材料準(zhǔn)備好后放入鍋中進(jìn)行煮,煮好后開始干飯。

在這里其實(shí)我們已經(jīng)能夠看出來(lái)問題,我們必須等到水燒開后才去準(zhǔn)備要煮的材料。回到概念里就是在同步模式下我們的代碼是依次執(zhí)行,后一個(gè)任務(wù)必須等待前一個(gè)任務(wù)結(jié)束才能開始執(zhí)行。程序執(zhí)行的順序和代碼編寫的順序是完全一致的。在單線程模式下,大多數(shù)任務(wù)都是以同步模式執(zhí)行。

異步模式

上個(gè)例子中我們?cè)诘却疅_的過(guò)程中什么都沒干,很浪費(fèi)時(shí)間,我們可以在燒水的過(guò)程中將食材都準(zhǔn)備好,等到水燒開后直接放入。

我們?cè)跓倪^(guò)程中去干了別的事情,就屬于異步模式,異步模式中不會(huì)等待異步任務(wù)的結(jié)束才開始執(zhí)行下一個(gè)同步的任務(wù),都是開啟過(guò)后就立即執(zhí)行下一個(gè)任務(wù)。

異步模式對(duì)于JS很重要,沒有異步模式的話我們就無(wú)法同時(shí)處理大量的耗時(shí)任務(wù),就會(huì)給用戶帶來(lái)卡頓和假死的體驗(yàn)。對(duì)于我們開發(fā)者來(lái)說(shuō),會(huì)給我們打開代碼執(zhí)行的順序混亂的問題。

EventLoop事件循環(huán)和消息隊(duì)列

  • EventLoop是一種循環(huán)機(jī)制,主線程從消息隊(duì)列中讀取任務(wù)并按照順序執(zhí)行,這個(gè)過(guò)程是循環(huán)不間斷的。

  • 消息隊(duì)列是存放異步任務(wù)的地方,當(dāng)我們的同步任務(wù)都執(zhí)行完畢后,EventLoop會(huì)從消息隊(duì)列中依次取出異步任務(wù)放到調(diào)用棧中進(jìn)行執(zhí)行。

宏任務(wù)和微任務(wù)

  • 宏任務(wù)可以理解為每次執(zhí)行棧執(zhí)行的代碼就是一個(gè)宏任務(wù)

    瀏覽器為了讓JS內(nèi)部宏任務(wù)與DOM操作能夠有序的執(zhí)行,會(huì)在一個(gè)宏任務(wù)執(zhí)行結(jié)束后,下一個(gè)宏任務(wù)執(zhí)行開始前,對(duì)頁(yè)面進(jìn)行重新渲染。

    宏任務(wù)包括:script整體代碼、setTimeout、setInterval、I/O、UI交互事件、MessageChannel等。

  • 微任務(wù)可以理解為每個(gè)宏任務(wù)執(zhí)行結(jié)束后立即執(zhí)行的任務(wù),發(fā)生在宏任務(wù)后,渲染之前,執(zhí)行微任務(wù)。

    所以微任務(wù)的響應(yīng)速度相比宏任務(wù)會(huì)更快,因?yàn)闊o(wú)需等待UI渲染

    微任務(wù)包括:Promise.then、MutaionObserver、process.nextTick(Node.js環(huán)境下)等。

圖片取自掘金,侵即刪

異步編程方案的本質(zhì)—回調(diào)函數(shù)

回調(diào)函數(shù):由調(diào)用者定制,交給執(zhí)行者執(zhí)行的函數(shù)。

我們通過(guò) callback 回調(diào)函數(shù)、事件發(fā)布/訂閱、Promise 等來(lái)組織代碼,本質(zhì)都是通過(guò)回調(diào)函數(shù)來(lái)實(shí)現(xiàn)異步代碼的存放與執(zhí)行。

更優(yōu)異步編程統(tǒng)一方案——Promise

Promise概述

Promise概念MDN傳送門

關(guān)于Promise概念性內(nèi)容就不在贅述了,可直接點(diǎn)擊傳送門前往MDN查看。簡(jiǎn)單來(lái)說(shuō)如果我們是用傳統(tǒng)的回調(diào)函數(shù)方式來(lái)完成復(fù)雜的異步流程,就會(huì)無(wú)法避免大量的回調(diào)函數(shù)嵌套,產(chǎn)生回調(diào)地獄的問題。為了避免回調(diào)地獄讓我們開始愉快的Promise的學(xué)習(xí)時(shí)光吧!

Promise案例

我們用Promise來(lái)封裝一個(gè)AJax

Promise的鏈?zhǔn)秸{(diào)用

誤區(qū)

  • 嵌套使用的方式是使用Promise最常見的誤區(qū)。我們要使用promise的鏈?zhǔn)秸{(diào)用的方法盡可能保證異步任務(wù)的扁平化。

鏈?zhǔn)秸{(diào)用的理解

  • promise對(duì)象then方法,返回了全新的promise對(duì)象??梢栽倮^續(xù)調(diào)用then方法,如果return的不是promise對(duì)象,而是一個(gè)值,那么這個(gè)值會(huì)作為resolve的值傳遞,如果沒有值,默認(rèn)是undefined

  • 后面的then方法就是在為上一個(gè)then返回的Promise注冊(cè)回調(diào)

  • 前面then方法中回調(diào)函數(shù)的返回值會(huì)作為后面then方法回調(diào)的參數(shù)

  • 如果回調(diào)中返回的是Promise,那后面then方法的回調(diào)會(huì)等待它的結(jié)束

Promise的異常處理

  • then中回調(diào)的onRejected方法

  • .catch()

了解更多,請(qǐng)點(diǎn)擊:https://www.bilibili.com/video/BV13a4y1n7tS/


作者:跟兔蟲
鏈接:https://juejin.cn/post/6913476532333707271
來(lái)源:掘金
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。


大前端進(jìn)擊之路(二)|JavaScript異步編程的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
浏阳市| 涞水县| 囊谦县| 肃南| 金乡县| 铜山县| 江陵县| 韶山市| 宝兴县| 东乡族自治县| 顺昌县| 什邡市| 浙江省| 大兴区| 张家口市| 聂拉木县| 乌鲁木齐县| 上蔡县| 桂阳县| 乐安县| 彭山县| 神木县| 宝应县| 乳山市| 临海市| 敦化市| 耿马| 利辛县| 泗水县| 江安县| 泌阳县| 张家川| 城步| 南陵县| 沾益县| 肥西县| 平昌县| 社会| 金沙县| 襄樊市| 葫芦岛市|