日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

js中的同步和異步,宏任務(wù)和微任務(wù),async和await

 印度阿三17 2020-02-28

所有的任務(wù)分為兩種,一種是同步任務(wù),一種是異步任務(wù)。

同步任務(wù)指的是,在主線程上排隊(duì)執(zhí)行的任務(wù),只有前一個(gè)任務(wù)執(zhí)行完畢,才能執(zhí)行后一個(gè)任務(wù);
異步任務(wù)指的是,不進(jìn)入主線程、而進(jìn)入"任務(wù)隊(duì)列"task queue)的任務(wù),只有等主線程任務(wù)執(zhí)行完畢,"任務(wù)隊(duì)列"開(kāi)始通知主線程,請(qǐng)求執(zhí)行任務(wù),該任務(wù)才會(huì)進(jìn)入主線程執(zhí)行。這里說(shuō)到了一個(gè)“隊(duì)列”(即任務(wù)隊(duì)列),該隊(duì)列放的是什么呢,放的就是setTimeout中的function,這些function依次加入該隊(duì)列,即該隊(duì)列中所有function中的程序?qū)?huì)在該隊(duì)列以外的所有代碼執(zhí)行完畢之后再以此執(zhí)行,這是為什么呢?因?yàn)樵趫?zhí)行程序的時(shí)候,瀏覽器會(huì)默認(rèn)setTimeout以及ajax請(qǐng)求這一類(lèi)的方法都是耗時(shí)程序(盡管可能不耗時(shí)),將其加入一個(gè)隊(duì)列中,該隊(duì)列是一個(gè)存儲(chǔ)耗時(shí)程序的隊(duì)列,在所有不耗時(shí)程序執(zhí)行過(guò)后,再來(lái)依次執(zhí)行該隊(duì)列中的程序。具體來(lái)說(shuō),異步運(yùn)行機(jī)制如下:

(1)所有同步任務(wù)都在主線程上執(zhí)行,形成一個(gè)執(zhí)行棧(execution context stack)。
(2)主線程之外,還存在一個(gè)"任務(wù)隊(duì)列"(task queue)。只要異步任務(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í)行棧,開(kāi)始執(zhí)行。
(4)主線程不斷重復(fù)上面的第三步。

setTimeOut函數(shù)為異步任務(wù),for循環(huán)為同步任務(wù),setTimeOut里的函數(shù)為回調(diào)函數(shù)。執(zhí)行順序?yàn)椋和絻?yōu)先,異步靠邊,回調(diào)墊底。所以即使setTimeOut的時(shí)間參數(shù)是0依然會(huì)放到任務(wù)隊(duì)列里,而不是主線程。主線程執(zhí)行完for循環(huán)以后才執(zhí)行異步任務(wù)setTimeOut。另外setTimeout()只是將事件插入了"任務(wù)隊(duì)列",必須等到當(dāng)前代碼(執(zhí)行棧)執(zhí)行完,主線程才會(huì)去執(zhí)行它指定的回調(diào)函數(shù)。要是當(dāng)前代碼耗時(shí)很長(zhǎng),有可能要等很久,所以并沒(méi)有辦法保證,回調(diào)函數(shù)一定會(huì)在setTimeout()指定的時(shí)間執(zhí)行。

javascript是單線程。單線程就意味著,所有任務(wù)需要排隊(duì),前一個(gè)任務(wù)結(jié)束,才會(huì)執(zhí)行后一個(gè)任務(wù)。如果前一個(gè)任務(wù)耗時(shí)很長(zhǎng),后一個(gè)任務(wù)就不得不一直等著。于是就有一個(gè)概念——任務(wù)隊(duì)列。如果排隊(duì)是因?yàn)橛?jì)算量大,CPU忙不過(guò)來(lái),倒也算了,但是很多時(shí)候CPU是閑著的,因?yàn)镮O設(shè)備(輸入輸出設(shè)備)很慢(比如Ajax操作從網(wǎng)絡(luò)讀取數(shù)據(jù)),不得不等著結(jié)果出來(lái),再往下執(zhí)行。于是JavaScript語(yǔ)言的設(shè)計(jì)者意識(shí)到,這時(shí)主線程完全可以不管IO設(shè)備,掛起處于等待中的任務(wù),先運(yùn)行排在后面的任務(wù)。等到IO設(shè)備返回了結(jié)果,再回過(guò)頭,把掛起的任務(wù)繼續(xù)執(zhí)行下去。

?

JavaScript的單線程,與它的用途有關(guān)。作為瀏覽器腳本語(yǔ)言,JavaScript的主要用途是與用戶(hù)互動(dòng),以及操作DOM。這決定了它只能是單線程,否則會(huì)帶來(lái)很復(fù)雜的同步問(wèn)題。比如,假定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)成這門(mén)語(yǔ)言的核心特征,將來(lái)也不會(huì)改變。

注:所謂單線程,是指在JS引擎中負(fù)責(zé)解釋和執(zhí)行JavaScript代碼的線程只有一個(gè)。

總結(jié):計(jì)算機(jī)中的同步就是排隊(duì)等待,假如你是第一百零一個(gè)備胎,那你只能等前面的一百個(gè)爆了之后才能‘處理'你。異步就是,盡管你是第一百零一個(gè),她還是能照顧到你的感受。

  • js是同步的?是的,單線程,那肯定只能同步(排隊(duì))執(zhí)行咯
  • js為什么需要異步?如果JS中不存在異步,只能自上而下執(zhí)行,萬(wàn)一上一行解析時(shí)間很長(zhǎng),那么下面的代碼就會(huì)被阻塞。對(duì)于用戶(hù)而言,阻塞就意味著"卡死",這樣就導(dǎo)致了很差的用戶(hù)體驗(yàn)

?例:

也就是說(shuō),setTimeout里的函數(shù)并沒(méi)有立即執(zhí)行,而是延遲了一段時(shí)間,滿(mǎn)足一定條件后,才去執(zhí)行的,這類(lèi)代碼,我們叫異步代碼。

總結(jié):同步可以保證順序一致,但是容易導(dǎo)致阻塞;異步可以解決阻塞問(wèn)題,但是會(huì)改變順序性,根據(jù)不同的需要去寫(xiě)你的代碼。

Promise是異步的,是指他的then()和catch()方法,Promise本身還是同步的,所以這里先執(zhí)行a變量?jī)?nèi)部的Promise同步代碼。(同步優(yōu)先)

注意?new Promise()?是同步方法,resolve才是異步方法。?

同步(Promise)>異步(微任務(wù)(process.nextTick ,Promises.then, Promise.catch ,resove,reject,MutationObserver)>宏認(rèn)為(setTimeout,setInterval,setImmediate))

process.nextTick> Promises.then

同步代碼執(zhí)行完成后,才會(huì)再去執(zhí)行異步,哪怕異步已經(jīng)到了執(zhí)行的時(shí)間了。

JavaScript的任務(wù)分為微任務(wù)(Microtasks)和宏任務(wù)(task);

  • 宏任務(wù)是主流,當(dāng)js開(kāi)始被執(zhí)行的時(shí)候,就是開(kāi)啟一個(gè)宏任務(wù),在宏任務(wù)中執(zhí)行一條一條的指令;
  • 宏任務(wù)可以同時(shí)有多個(gè),但會(huì)按順序一個(gè)一個(gè)執(zhí)行;
  • 每一個(gè)宏任務(wù),后面都可以跟一個(gè)微任務(wù)隊(duì)列,如果微任務(wù)隊(duì)列中有指令或方法,那么就會(huì)執(zhí)行;如果沒(méi)有,則開(kāi)始執(zhí)行下一個(gè)宏任務(wù),直到所有的宏任務(wù)執(zhí)行完為止,微任務(wù)相當(dāng)于宏任務(wù)的小尾巴;
  • 為什么有了宏任務(wù),還會(huì)有微任務(wù)存在?因?yàn)楹耆蝿?wù)太占用性能,當(dāng)需要一些較早就準(zhǔn)備好的方法,排在最后才執(zhí)行的時(shí)候,又不想新增一個(gè)宏任務(wù),那么就可以把這些方法,一個(gè)一個(gè)的放在微任務(wù)隊(duì)列里面,在這個(gè)宏任務(wù)中的代碼執(zhí)行完后,就會(huì)執(zhí)行微任務(wù)隊(duì)列。

 [宏任務(wù):macro?task]

????????- 定時(shí)器

????????-?事件綁定

????????-?ajax

????????-?回調(diào)函數(shù)

????????-?Node中fs可以進(jìn)行異步的I/O操作

[微任務(wù):micro?task]

????????-?Promise(async/await)??=>?Promise并不是完全的同步,當(dāng)在Excutor中執(zhí)行resolve或者reject的時(shí)候,此時(shí)是異步操作,會(huì)先執(zhí)行then/catch等,當(dāng)主棧完成后,才會(huì)再去調(diào)用resolve/reject把存放的方法執(zhí)行

????????-?process.nextTick (node中實(shí)現(xiàn)的api,把當(dāng)前任務(wù)放到主棧最后執(zhí)行,當(dāng)主棧執(zhí)行完,先執(zhí)行nextTick,再到等待隊(duì)列中找)

   -?MutationObserver? ?(創(chuàng)建并返回一個(gè)新的?MutationObserver?它會(huì)在指定的DOM發(fā)生變化時(shí)被調(diào)用。)

任務(wù)隊(duì)列到達(dá)時(shí)間后先進(jìn)先出的原則

?

參考:

1:https://blog.csdn.net/qq_40959677/article/details/95961443

2:https://www.baidu.com/link?url=SBAnO_y-vTjtcvs-NQlfPeEKW1NTRrXP1yiYhf-nLeBvf88WbIi01LvhphfWFKRrR1ay8KFy0rWDuAM1B4M5An-n3nbVVXSmnB0MD2Td7TK&wd=&eqid=b29f3105000520ac000000065e54ed37

?

~李疆 發(fā)布了323 篇原創(chuàng)文章 · 獲贊 128 · 訪問(wèn)量 13萬(wàn) 私信 關(guān)注 來(lái)源:http://www./content-4-643401.html

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多