nodejs中怎么循環(huán)瀏覽器事件,相信很多沒(méi)有經(jīng)驗(yàn)的人對(duì)此束手無(wú)策,為此本文總結(jié)了問(wèn)題出現(xiàn)的原因和解決方法,通過(guò)這篇文章希望你能解決這個(gè)問(wèn)題。
公司主營(yíng)業(yè)務(wù):網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計(jì)、移動(dòng)網(wǎng)站開(kāi)發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實(shí)現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競(jìng)爭(zhēng)能力。創(chuàng)新互聯(lián)是一支青春激揚(yáng)、勤奮敬業(yè)、活力青春激揚(yáng)、勤奮敬業(yè)、活力澎湃、和諧高效的團(tuán)隊(duì)。公司秉承以“開(kāi)放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對(duì)我們的高要求,感謝他們從不同領(lǐng)域給我們帶來(lái)的挑戰(zhàn),讓我們激情的團(tuán)隊(duì)有機(jī)會(huì)用頭腦與智慧不斷的給客戶帶來(lái)驚喜。創(chuàng)新互聯(lián)推出泗陽(yáng)免費(fèi)做網(wǎng)站回饋大家。
瀏覽器中的事件循環(huán):
為了協(xié)調(diào)事件(event),用戶交互(user interaction),腳本(script),渲染(rendering),網(wǎng)絡(luò)(networking)等,用戶代理(user agent)必須使用 事件循環(huán)(event loops).
事件:PostMessage(多個(gè)頁(yè)面通信),MutationObserver(dom監(jiān)聽(tīng))等
用戶交互:click,onScroll等
渲染:解析dom,css等
腳本:執(zhí)行腳本
nodejs中的事件循環(huán)
事件循環(huán)允許Node.js執(zhí)行非阻塞I/O操作,盡管JavaScript是單線程的,通過(guò)盡可能將操作卸載到系統(tǒng)內(nèi)核,由于大多數(shù)現(xiàn)代內(nèi)核都是多線程的,因此 他們可以處理在后臺(tái)執(zhí)行的多個(gè)操作。當(dāng)其中一個(gè)操作完成時(shí),內(nèi)核會(huì)告訴Nodejs,以便可以將相應(yīng)的回調(diào)添加到輪詢隊(duì)列中以最終執(zhí)行。
事件:EventEmitter
非阻塞I/O: 網(wǎng)絡(luò)請(qǐng)求,文件讀寫等
腳本: js執(zhí)行腳本
事件循環(huán)的本質(zhì)
在瀏覽器或者nodejs環(huán)境中,運(yùn)行時(shí)對(duì)js腳本的調(diào)度方式就叫事件循環(huán)
setTimeout(()=>{ console.log('setTimeout') },0) Promise.resolve().then(() =>{ console.log('promise') }) console.log('main') // main promise setTimeout
javascript為什么是單線程的?
瀏覽器js的作用是操作DOM,這決定了它只能是單線程,否則會(huì)帶來(lái)很復(fù)雜的同步問(wèn)題。比如,假定javascript同時(shí)有兩個(gè)線程,一個(gè)線程在某個(gè)DOM 節(jié)點(diǎn)上添加內(nèi)容,另一個(gè)線程刪除了這個(gè)節(jié)點(diǎn),這時(shí)瀏覽器不知道以哪個(gè)線程為主。
任務(wù)隊(duì)列
單線程意味著所有任務(wù)需要排隊(duì),如果因?yàn)槿蝿?wù)cpu計(jì)算量大還好,但是I/O操作cpu是閑著的。所以js就設(shè)計(jì)成了一門異步語(yǔ)言,不會(huì)做無(wú)謂的等待。
任務(wù)可以分成兩種,一種是同步任務(wù),另一種是異步任務(wù)。
所有同步任務(wù)都在主線程上執(zhí)行,形成一個(gè)執(zhí)行棧。
主線程之外,還存在一個(gè)任務(wù)隊(duì)列。只要異步任務(wù)有了運(yùn)行結(jié)果,就在任務(wù)隊(duì)列之中放置一個(gè)事件。
一旦執(zhí)行棧中的所有同步任務(wù)執(zhí)行完畢,系統(tǒng)就會(huì)讀取任務(wù)隊(duì)列,看看里面有哪些事件。那些對(duì)應(yīng)的異步任務(wù),于是結(jié)束等待狀態(tài),進(jìn)入執(zhí)行棧,開(kāi)始執(zhí)行。
主線程不斷重復(fù)上面的第三步
主線程從任務(wù)隊(duì)列中讀取事件,這個(gè)過(guò)程是循環(huán)不斷的,所以整個(gè)的這種運(yùn)行機(jī)制又稱 Event Loop(事件循環(huán))
宏任務(wù)和微任務(wù)
除了廣義的同步任務(wù)和異步任務(wù),javaScript單線程中的任務(wù)可以細(xì)分為 宏任務(wù)和微任務(wù)。
macrotask(宏任務(wù)): script(整體代碼),setTimeout, setInterval, setImmediate, I/O, UI rendering
microtask(微任務(wù)):process.nextTick, Promise, Object.observe, MutationObserver 1.宏任務(wù)進(jìn)入主線程,執(zhí)行過(guò)程中會(huì)搜集微任務(wù)加入微任務(wù)隊(duì)列。 2.宏任務(wù)執(zhí)行完成之后,立馬執(zhí)行微任務(wù)中的任務(wù)。微任務(wù)執(zhí)行過(guò)程中將再次收集宏任務(wù),并加入宏任務(wù)隊(duì)列 3.反復(fù)執(zhí)行1,2
事件循環(huán):每執(zhí)行完一輪宏任務(wù)和微任務(wù)就叫做一環(huán)事件;
一輪事件循環(huán)會(huì)執(zhí)行一次宏任務(wù)以及所有的微任務(wù)
setTimeout(() => { console.log('setTimeout') setTimeout(() => { console.log('setTimeout2') },0) },0) Promise.resolve().then(() =>{ console.log('Promise') Promise.resolve().then(() =>{ console.log('Promise2') }) }) console.log('main') // main promise promise2 setTimeout
任務(wù)隊(duì)列一定會(huì)保持先進(jìn)先出的順序執(zhí)行,沒(méi)次只能執(zhí)行一個(gè)紅任務(wù)?。?!·
setTimeout(() => { // 兩個(gè)setTimeout誰(shuí)先進(jìn)的話 誰(shuí)就先出 console.log('setTimeout') Promise.resolve().then(() =>{ console.log('promise') }) },0) Promise.resolve().then(() =>{ console.log('promise2') setTimeout(() => { console.log('setTimeout2') },0) }) console.log('main') // main promise2 setTimeout promise setTimeout2
new Promise((res, rej) =>{ console.log(1) res() }).then(() =>{ console.log(2) new Promise((res,rej) =>{ console.log(3) res() }).then(() =>{ console.log(4) }).then(() =>{ console.log(5) }).then(() =>{ console.log(6) }) }).then(() =>{ console.log(7) }) .then(() =>{ console.log(8) }) // 1 2 3 4 7 5 8 6
看完上述內(nèi)容,你們掌握nodejs中怎么循環(huán)瀏覽器事件的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!