本文實例講述了node.js中對Event Loop事件循環(huán)的理解與應(yīng)用。分享給大家供大家參考,具體如下:
站在用戶的角度思考問題,與客戶深入溝通,找到開魯網(wǎng)站設(shè)計與開魯網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗,讓設(shè)計與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個性化、用戶體驗好的作品,建站類型包括:做網(wǎng)站、成都做網(wǎng)站、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣、域名與空間、虛擬主機、企業(yè)郵箱。業(yè)務(wù)覆蓋開魯?shù)貐^(qū)。
javascript是單線程的,所以任務(wù)的執(zhí)行都需要排隊,任務(wù)分為兩種,一種是同步任務(wù),一種是異步任務(wù)。
同步任務(wù)是進(jìn)入主線程上排隊執(zhí)行的任務(wù),上一個任務(wù)執(zhí)行完了,下一個任務(wù)才會執(zhí)行。
異步任務(wù)是不進(jìn)入主線程,而是進(jìn)入一個 "任務(wù)隊列" 里,"任務(wù)隊列" 通知主線程,該異步任務(wù)才會進(jìn)入主線程執(zhí)行。
任務(wù)的運行機制如下:
1、所有同步任務(wù)在主線程上執(zhí)行,形成一個 "執(zhí)行棧",注意棧是先進(jìn)后出的。
2、主線程外,有一個 "任務(wù)隊列" ,只要異步任務(wù)處理完有結(jié)果了,就在 "任務(wù)隊列" 中放置一個事件,注意隊列是先進(jìn)先出的。
3、一旦 "執(zhí)行棧" 中所有同步任務(wù)執(zhí)行完畢。系統(tǒng)讀取 "任務(wù)隊列" 中的事件,對應(yīng)的異步任務(wù)。放入 "執(zhí)行棧" 中,開始執(zhí)行。
4、主線程不斷重復(fù)第三步,這種循環(huán)從 "任務(wù)隊列" 中讀取事件處理的這種運行機制稱為Event Loop(事件循環(huán))。
"執(zhí)行棧" 中的同步代碼總是比 "任務(wù)隊列"中的異步任務(wù)之前運行。
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ù)隊列" 是一個隊列,隊列的特性是先進(jìn)先出??聪旅娲a:
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)入隊列,所以會先運行。
對于異步操作,像ajax,只有操作成功后返回結(jié)果,才會進(jìn)入 "任務(wù)隊列" 中,而不是調(diào)用的時候就放入隊列中??聪旅娲a:
Title
ajax() 與 setTimeout 誰先進(jìn)入隊列,誰先輸出,是需要看兩者消耗時間,誰更短。時間短的會先進(jìn)入隊列先運行。
setTimeout 與 setInterval 運行機制一樣,都是在指定時間把事件插入到 "任務(wù)隊列" 尾部。區(qū)別是前者只執(zhí)行一次,后者可反復(fù)執(zhí)行。
node.js 還為我們提供了,process.nextTick 和 setImmediate 與 "任務(wù)隊列" 有關(guān)的方法。
process.nextTick 會把回調(diào)函數(shù)放在當(dāng)前 "執(zhí)行棧" 的尾部。也就是說是在讀取 "任務(wù)隊列" 之前運行。
function fun() { console.log(1); setTimeout(function () { console.log(2); }, 0); process.nextTick(function () { console.log(3); process.nextTick(function () { console.log(4); }); }); process.nextTick(function () { console.log(5); }); console.log(6); } fun();
上面的代碼會輸出 1 6 3 5 4 2 ,注意process.nextTick會把回調(diào)函數(shù)放在 "執(zhí)行棧" 的尾部。
同步代碼最先輸出 1 6,然后 3 的先放入尾部,然后 5 的跟在 3 后面。3先執(zhí)行,然后把 4 放入到 5 的后面。5執(zhí)行完后,再執(zhí)行4,最后讀取 "任務(wù)隊列" 中的輸出2。
setImmediate 會把回調(diào)函數(shù)放在當(dāng)前 "任務(wù)隊列" 的尾部。也就是下一次事件循環(huán)Event Loop時執(zhí)行。
function fun() { console.log(1); setTimeout(function () { console.log(2); }, 0); setImmediate(function () { console.log(3); }); console.log(4); } fun();
上面的代碼是會輸出 1 4 2 3 還是 1 4 3 2 是不確定的,因為setTimeout 與 setImmediate 都會在下一次事件循環(huán)Event Loop中觸發(fā),所以輸出是不確定的。
希望本文所述對大家node.js程序設(shè)計有所幫助。