本文實(shí)例講述了node.js中對Event Loop事件循環(huán)的理解與應(yīng)用。分享給大家供大家參考,具體如下:
javascript是單線程的,所以任務(wù)的執(zhí)行都需要排隊(duì),任務(wù)分為兩種,一種是同步任務(wù),一種是異步任務(wù)。
同步任務(wù)是進(jìn)入主線程上排隊(duì)執(zhí)行的任務(wù),上一個任務(wù)執(zhí)行完了,下一個任務(wù)才會執(zhí)行。
異步任務(wù)是不進(jìn)入主線程,而是進(jìn)入一個 "任務(wù)隊(duì)列" 里,"任務(wù)隊(duì)列" 通知主線程,該異步任務(wù)才會進(jìn)入主線程執(zhí)行。
任務(wù)的運(yùn)行機(jī)制如下:
1、所有同步任務(wù)在主線程上執(zhí)行,形成一個 "執(zhí)行棧",注意棧是先進(jìn)后出的。
2、主線程外,有一個 "任務(wù)隊(duì)列" ,只要異步任務(wù)處理完有結(jié)果了,就在 "任務(wù)隊(duì)列" 中放置一個事件,注意隊(duì)列是先進(jìn)先出的。
3、一旦 "執(zhí)行棧" 中所有同步任務(wù)執(zhí)行完畢。系統(tǒng)讀取 "任務(wù)隊(duì)列" 中的事件,對應(yīng)的異步任務(wù)。放入 "執(zhí)行棧" 中,開始執(zhí)行。
4、主線程不斷重復(fù)第三步,這種循環(huán)從 "任務(wù)隊(duì)列" 中讀取事件處理的這種運(yùn)行機(jī)制稱為Event Loop(事件循環(huán))。
"執(zhí)行棧" 中的同步代碼總是比 "任務(wù)隊(duì)列"中的異步任務(wù)之前運(yùn)行。
function fun() { setTimeout(function () { console.log('異步任務(wù)'); }, 0); console.log(1); console.log(2); console.log(3); console.log(4); console.log(5);}fun();上面的代碼,console.log代碼寫在setTimeout后面,但仍然先執(zhí)行。
"任務(wù)隊(duì)列" 是一個隊(duì)列,隊(duì)列的特性是先進(jìn)先出。看下面代碼:
function fun() { console.log(1); setTimeout(function () { console.log(2); setTimeout(function () { console.log(3); }, 0); }, 0); console.log(4);}fun();輸出結(jié)果為 1 4 2 3,打印 2 的setTimeout任務(wù)比打印 3 的setTimeout任務(wù)先進(jìn)入隊(duì)列,所以會先運(yùn)行。
對于異步操作,像ajax,只有操作成功后返回結(jié)果,才會進(jìn)入 "任務(wù)隊(duì)列" 中,而不是調(diào)用的時候就放入隊(duì)列中。看下面代碼:
<!DOCTYPE html><html lang="zh-CN"><head> <meta charset="UTF-8"> <title>Title</title></head><body><script> function ajax() { var xhr = new XMLHttpRequest(); xhr.open('GET', 'https://mail.163.com/', true); xhr.send(); xhr.onreadystatechange = function () { if (xhr.readyState == 4 && xhr.status == 200) { console.log(xhr.responseText); } }; } function fun() { console.log(1); ajax(); setTimeout(function () { console.log(2); }, 1000); console.log(3); } fun();</script></body></html>ajax() 與 setTimeout 誰先進(jìn)入隊(duì)列,誰先輸出,是需要看兩者消耗時間,誰更短。時間短的會先進(jìn)入隊(duì)列先運(yùn)行。
新聞熱點(diǎn)
疑難解答
圖片精選