web前端tips:js的事件循環(huán)(Event Loop)

<p>
</p><p class="image-package"><img class="uploaded-img" src="https://upload-images.jianshu.io/upload_images/28907010-c855c60155108346.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" width="auto" height="auto"/></p><p><strong>一贾惦、介紹</strong></p><p><strong>1. 什么是js的事件循環(huán)</strong></p><p>JavaScript事件循環(huán)是一種處理異步事件和回調(diào)函數(shù)的機(jī)制敞峭,它是JavaScript實(shí)現(xiàn)異步編程的核心渠驼。它在瀏覽器或Node.js環(huán)境中運(yùn)行敢会,用于管理任務(wù)隊(duì)列和調(diào)用棧,以及在適當(dāng)?shù)臅r(shí)候執(zhí)行回調(diào)函數(shù)陷谱。</p><p><strong>2. 為什么會(huì)出現(xiàn)js的事件循環(huán)</strong></p><p>JavaScript事件循環(huán)是為了解決JavaScript作為<strong>單線程</strong>語(yǔ)言時(shí)的并發(fā)性問(wèn)題而設(shè)計(jì)的。由于JavaScript是單線程的瑟蜈,因此在執(zhí)行代碼時(shí)不能同時(shí)執(zhí)行多個(gè)任務(wù)烟逊。這種單一線程的特性可能會(huì)導(dǎo)致JavaScript在處理某些長(zhǎng)時(shí)間運(yùn)行的操作(如網(wǎng)絡(luò)請(qǐng)求、文件系統(tǒng)訪問(wèn)等)時(shí)出現(xiàn)阻塞铺根,從而影響用戶體驗(yàn)宪躯。
為了解決這些問(wèn)題,JavaScript引入了異步編程模型和事件循環(huán)機(jī)制位迂,它可以監(jiān)聽(tīng)消息隊(duì)列中的事件并根據(jù)優(yōu)先級(jí)順序依次執(zhí)行相應(yīng)的回調(diào)函數(shù)访雪。這種機(jī)制允許JavaScript在等待某些操作完成的同時(shí),可以執(zhí)行其他任務(wù)掂林,從而避免了阻塞臣缀,提高了效率和并發(fā)性,使得開(kāi)發(fā)者可以使用異步編程模型來(lái)處理復(fù)雜的泻帮、長(zhǎng)時(shí)間運(yùn)行的操作精置,同時(shí)提供更好的用戶體驗(yàn)。</p><p><strong>3. 事件循環(huán)的流程</strong></p><p>事件循環(huán)中的任務(wù)分為兩類:同步任務(wù)和異步任務(wù)锣杂。同步任務(wù)是按照代碼順序依次執(zhí)行的任務(wù)脂倦,而異步任務(wù)則是在任務(wù)隊(duì)列中等待執(zhí)行的任務(wù),例如定時(shí)器回調(diào)函數(shù)元莫、事件回調(diào)函數(shù)和Promise回調(diào)函數(shù)等赖阻。異步任務(wù)又可以分為宏任務(wù)和微任務(wù),微任務(wù)的執(zhí)行優(yōu)先級(jí)高于宏任務(wù)踱蠢。當(dāng)一個(gè)宏任務(wù)中的所有微任務(wù)都執(zhí)行完畢后火欧,才會(huì)執(zhí)行下一個(gè)宏任務(wù)。事件循環(huán)的工作流程是不斷地從任務(wù)隊(duì)列中取出任務(wù)并執(zhí)行朽基,直到隊(duì)列為空為止布隔。</p><p><strong>二、事件循環(huán)的應(yīng)用場(chǎng)景</strong></p><ol><li><p>DOM 事件處理:通過(guò)監(jiān)聽(tīng) DOM 事件(例如 click稼虎、scroll 等)衅檀,可以使用事件循環(huán)來(lái)異步更新 UI 或執(zhí)行其他操作。</p></li><li><p>定時(shí)器:使用?<strong>setTimeout()</strong>?和?<strong>setInterval()</strong>?函數(shù)可以創(chuàng)建定時(shí)器霎俩,用于在指定時(shí)間間隔之后執(zhí)行相應(yīng)的操作哀军。這些操作會(huì)被作為異步任務(wù)添加到任務(wù)隊(duì)列中等待執(zhí)行沉眶。</p></li><li><p>網(wǎng)絡(luò)請(qǐng)求:當(dāng) JavaScript 需要發(fā)送網(wǎng)絡(luò)請(qǐng)求時(shí),可以使用?<strong>XMLHttpRequest</strong>?或?<strong>fetch</strong>?API 發(fā)送異步請(qǐng)求杉适,并將響應(yīng)數(shù)據(jù)作為異步任務(wù)加入到任務(wù)隊(duì)列中等待處理谎倔。</p></li><li><p>Promise 和 async/await:Promise 和 async/await 是 JavaScript 中常用的異步編程方式,實(shí)際上它們底層都是基于事件循環(huán)機(jī)制實(shí)現(xiàn)的猿推。通過(guò)將回調(diào)函數(shù)封裝為 Promise 對(duì)象或 async 函數(shù)片习,可以讓異步代碼更加易讀、易維護(hù)蹬叭。</p></li><li><p>Web Workers:Web Workers 可以讓 JavaScript 在多線程環(huán)境下運(yùn)行藕咏,從而避免阻塞主線程。Web Workers 使用了與事件循環(huán)類似的消息隊(duì)列機(jī)制來(lái)實(shí)現(xiàn)異步通信秽五。</p></li></ol><p><strong>三孽查、例子</strong></p><p>1. 定時(shí)器回調(diào)函數(shù)</p><pre>console.log('start');
setTimeout(()?=>?{
??console.log('timer');
},?0);
console.log('end');
//?輸出結(jié)果
//?start
//?end
//?timer</pre><p>這是因?yàn)閟etTimeout()方法是異步執(zhí)行的,它會(huì)在指定時(shí)間后將回調(diào)函數(shù)添加到任務(wù)隊(duì)列中等待執(zhí)行坦喘。因此盲再,在輸出"start"和"end"之后,程序立即返回瓣铣,等到下一個(gè)事件循環(huán)時(shí)才執(zhí)行定時(shí)器回調(diào)函數(shù)答朋。</p><p>2. Promise回調(diào)函數(shù)</p><pre>console.log('start');
Promise.resolve().then(()?=>?{
??console.log('promise');
});
console.log('end');
//?輸出結(jié)果
//?start
//?end
//?promise</pre><p>這是因?yàn)镻romise回調(diào)函數(shù)是微任務(wù),它的執(zhí)行優(yōu)先級(jí)高于宏任務(wù)棠笑,因此在輸出"start"和"end"之后绿映,先執(zhí)行Promise回調(diào)函數(shù),再執(zhí)行下一個(gè)宏任務(wù)腐晾。</p><p>3. 事件回調(diào)函數(shù)</p><pre>console.log('start');
document.addEventListener('click',?()?=>?{
??console.log('click');
});
console.log('end');
//?輸出結(jié)果
//?start
//?end</pre><p>這是因?yàn)槭录卣{(diào)函數(shù)需要等待用戶操作才能觸發(fā)叉弦,因此在程序執(zhí)行完畢之后,等待用戶操作后才會(huì)將回調(diào)函數(shù)添加到任務(wù)隊(duì)列中等待執(zhí)行藻糖。</p><p><strong>四淹冰、復(fù)雜例子思考</strong></p><pre>async?function?a()?{
??console.log('async-a');
??await?b();
??console.log('async-b');
};

async?function?b()?{
??console.log('async-b');
};
console.log('start');

setTimeout(()=>{
??console.log('setTimeout-1');
},1000);
setTimeout(()=>{
??console.log('setTimeout-2');

??new?Promise((resolve,reject)=>{
????console.log('setTimeout-promise');
????resolve('promise-1');
??}).then(res?=>?{
????console.log(res);
??})
},0);

new?Promise((resolve,reject)=>{
??console.log('promise');
??resolve('promise-2');
}).then(res?=>?{
??console.log(res);
});

a();

console.log('end')</pre><p><strong>五、一句話總結(jié)</strong></p><p>JavaScript事件循環(huán)是一種處理異步事件和回調(diào)函數(shù)的機(jī)制巨柒,它是JavaScript實(shí)現(xiàn)異步編程的核心樱拴。它會(huì)不斷地從任務(wù)隊(duì)列中取出任務(wù)并執(zhí)行,直到任務(wù)隊(duì)列為空為止洋满。事件循環(huán)中的任務(wù)分為同步任務(wù)和異步任務(wù)晶乔,異步任務(wù)又可以分為宏任務(wù)和微任務(wù),微任務(wù)的執(zhí)行優(yōu)先級(jí)高于宏任務(wù)牺勾。</p><p><strong>六正罢、結(jié)語(yǔ)</strong></p><p>牽手 持續(xù)為你分享各類知識(shí)和軟件 ,歡迎訪問(wèn)驻民、關(guān)注翻具、討論 并留下你的小心心?</p>

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末履怯,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子裆泳,更是在濱河造成了極大的恐慌叹洲,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,546評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件工禾,死亡現(xiàn)場(chǎng)離奇詭異运提,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)闻葵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門糙捺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人笙隙,你說(shuō)我怎么就攤上這事】茬裕” “怎么了竟痰?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,911評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)掏呼。 經(jīng)常有香客問(wèn)我坏快,道長(zhǎng),這世上最難降的妖魔是什么憎夷? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,737評(píng)論 1 294
  • 正文 為了忘掉前任莽鸿,我火速辦了婚禮,結(jié)果婚禮上拾给,老公的妹妹穿的比我還像新娘祥得。我一直安慰自己,他們只是感情好蒋得,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布级及。 她就那樣靜靜地躺著,像睡著了一般额衙。 火紅的嫁衣襯著肌膚如雪饮焦。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,598評(píng)論 1 305
  • 那天窍侧,我揣著相機(jī)與錄音县踢,去河邊找鬼。 笑死伟件,一個(gè)胖子當(dāng)著我的面吹牛硼啤,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播斧账,決...
    沈念sama閱讀 40,338評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼丙曙,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼爸业!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起亏镰,我...
    開(kāi)封第一講書(shū)人閱讀 39,249評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤扯旷,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后索抓,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體钧忽,經(jīng)...
    沈念sama閱讀 45,696評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評(píng)論 3 336
  • 正文 我和宋清朗相戀三年逼肯,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了耸黑。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,013評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡篮幢,死狀恐怖大刊,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情三椿,我是刑警寧澤缺菌,帶...
    沈念sama閱讀 35,731評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站搜锰,受9級(jí)特大地震影響伴郁,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蛋叼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評(píng)論 3 330
  • 文/蒙蒙 一焊傅、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧狈涮,春花似錦狐胎、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,929評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至骆姐,卻和暖如春镜粤,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背玻褪。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,048評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工肉渴, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人带射。 一個(gè)月前我還...
    沈念sama閱讀 48,203評(píng)論 3 370
  • 正文 我出身青樓同规,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子券勺,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容