所有的任務(wù)分為兩種,一種是同步任務(wù),一種是異步任務(wù)。 同步任務(wù)指的是,在主線程上排隊(duì)執(zhí)行的任務(wù),只有前一個(gè)任務(wù)執(zhí)行完畢,才能執(zhí)行后一個(gè)任務(wù); (1)所有同步任務(wù)都在主線程上執(zhí)行,形成一個(gè)執(zhí)行棧(execution context stack)。 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è),她還是能照顧到你的感受。
?例: 也就是說(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)先) 注意? 同步(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ù):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 ? ![]() ![]() |
|
來(lái)自: 印度阿三17 > 《開(kāi)發(fā)》