JavaScript運(yùn)行機(jī)制

一.js是一門單線程的語言,js是按照語句出現(xiàn)的順序執(zhí)行的

二.Javascript事件循環(huán)

因?yàn)閖s是單線程渣窜,所有js任務(wù)要一個一個順序執(zhí)行,任務(wù)分為:


???????????? 同步任務(wù)


????????????? 異步任務(wù)


流程圖:


任務(wù)進(jìn)入執(zhí)行椃稳唬——>同步任務(wù)還是異步任務(wù)艺蝴?


同步任務(wù)——>主線程——>任務(wù)全部執(zhí)行完畢——>讀取任務(wù)隊(duì)列中的結(jié)果,進(jìn)入主線程執(zhí)行


異步任務(wù)——>event table——>注冊回調(diào)函數(shù)——>event queue——>讀取任務(wù)隊(duì)列中的結(jié)果杂穷,進(jìn)入主線程執(zhí)行


上面的過程不斷重復(fù)——就是常說的Event? Loop(事件循環(huán))


let data = [];

$.ajax({

url:www.javascript.com,

data:data,

success:() => { console.log('發(fā)送成功!'); } })

console.log('代碼執(zhí)行結(jié)束')

分析:1.ajax進(jìn)入Event Table悍缠,注冊回調(diào)函數(shù) success()

2.執(zhí)行同步任務(wù) console.log('代碼執(zhí)行結(jié)束')

3.ajax事件完成,回調(diào)函數(shù) 進(jìn)入event queue

4.主線程 從event? queue中讀取 回調(diào)函數(shù)success 并執(zhí)行


setTimeout

setTimeout(() => { task() },3000)

sleep(10000000)

分析:1.task()進(jìn)入event? table并注冊耐量,計(jì)時開始

2.執(zhí)行同步任務(wù) sleep()

3.3秒到了飞蚓,但是同步任務(wù)未完成,所以event queue中仍需等待

4.執(zhí)行完廊蜒,task()從 event queue進(jìn)入主線程執(zhí)行趴拧,延遲時間大于3秒

setTimeout(fn,0)

指某個任務(wù)在主線程最早可得的空閑時間執(zhí)行,即主線程執(zhí)行棧中的同步任務(wù)完成后山叮,立即執(zhí)行fn,0毫秒是達(dá)不到的著榴,最低是4毫秒



setInterval

會每隔指定的時間將注冊的函數(shù)置入 event? queue


setInterval(fn, ms):? 不是每過ms 會執(zhí)行一次fn,而是屁倔,沒過ms脑又,會有fn進(jìn)入event? queue,一旦fn執(zhí)行時間超過了延遲時間ms锐借,那就看不出來有時間間隔了



Promise 與 process.nextTick(callback)

process.nextTick(callback)類似 node.js版的“setTimeout”问麸,在事件循環(huán)的下一次循環(huán)中調(diào)用callback回調(diào)函數(shù)

任務(wù)更精細(xì)的定義:

宏任務(wù): 包括整體代碼script, setTimeout瞎饲, setInterval

微任務(wù):promise, process.nextTick

事件循環(huán)循序:進(jìn)入整體代碼(宏任務(wù))后炼绘,開始第一次循環(huán)嗅战,接著執(zhí)行所有的微任務(wù),然后再次從宏任務(wù)開始俺亮,找到其中一個任務(wù)隊(duì)列執(zhí)行完畢驮捍,再執(zhí)行所有的微任務(wù)

setTimeout(function() { console.log('setTimeout'); })

new Promise(function(resolve) { console.log('promise');

}).then(function() { console.log('then'); })

console.log('console')

// promise?

//console

//undefined

//setTimeout

分析:1.這段代碼作為宏任務(wù),進(jìn)入主線程

2.先遇到settimout,那么將其回調(diào)函數(shù)注冊后分發(fā)到宏任務(wù)event queue

3.接下來promise脚曾,立即執(zhí)行东且,并將then函數(shù)分發(fā)到微任務(wù)event queue

4.遇到 console.log并執(zhí)行

5.整體代碼script作為第一個宏任務(wù)執(zhí)行結(jié)束,看看有哪些微任務(wù)本讥?then函數(shù)在微任務(wù)中珊泳,并執(zhí)行

6.第一輪事件循環(huán)結(jié)束后鲁冯,開始第二輪循環(huán),從宏任務(wù)event queue開始色查,發(fā)現(xiàn) 了宏任務(wù) setimout對應(yīng)的回調(diào)函數(shù)薯演,立即執(zhí)行

7.結(jié)束

console.log('1');

setTimeout(function() {

console.log('2');

process.nextTick(function() { console.log('3'); })

new Promise(function(resolve) {

console.log('4');

resolve();

}).then(function() { console.log('5') }) })

process.nextTick(function() { console.log('6'); })

new Promise(function(resolve) {

console.log('7');

resolve(); }).

then(function() { console.log('8') })

setTimeout(function() { console.log('9');

process.nextTick(function() { console.log('10'); })

new Promise(function(resolve) { console.log('11');

resolve();

}).then(function() { console.log('12') }) })

分析

第一輪事件循環(huán)流程分析如下:

整體script作為第一個宏任務(wù)進(jìn)入主線程,遇到console.log秧了,輸出1跨扮。

遇到setTimeout,其回調(diào)函數(shù)被分發(fā)到宏任務(wù)Event Queue中验毡。我們暫且記為setTimeout1衡创。

遇到process.nextTick(),其回調(diào)函數(shù)被分發(fā)到微任務(wù)Event Queue中晶通。我們記為process1璃氢。

遇到Promise遮斥,new Promise直接執(zhí)行墩朦,輸出7。then被分發(fā)到微任務(wù)Event Queue中匿又。我們記為then1隘竭。

又遇到了setTimeout塘秦,其回調(diào)函數(shù)被分發(fā)到宏任務(wù)Event Queue中,我們記為setTimeout2动看。

宏任務(wù)Event Queue微任務(wù)Event Queue

setTimeout1process1

setTimeout2then1

上表是第一輪事件循環(huán)宏任務(wù)結(jié)束時各Event Queue的情況尊剔,此時已經(jīng)輸出了1和7。

我們發(fā)現(xiàn)了process1和then1兩個微任務(wù)菱皆。

執(zhí)行process1,輸出6须误。

執(zhí)行then1,輸出8仇轻。

好了京痢,第一輪事件循環(huán)正式結(jié)束,這一輪的結(jié)果是輸出1篷店,7祭椰,6,8疲陕。那么第二輪時間循環(huán)從setTimeout1宏任務(wù)開始:

首先輸出2方淤。接下來遇到了process.nextTick(),同樣將其分發(fā)到微任務(wù)Event Queue中蹄殃,記為process2携茂。new Promise立即執(zhí)行輸出4,then也分發(fā)到微任務(wù)Event Queue中诅岩,記為then2讳苦。

宏任務(wù)Event Queue微任務(wù)Event Queue

setTimeout2process2

then2

第二輪事件循環(huán)宏任務(wù)結(jié)束带膜,我們發(fā)現(xiàn)有process2和then2兩個微任務(wù)可以執(zhí)行。

輸出3医吊。

輸出5钱慢。

第二輪事件循環(huán)結(jié)束,第二輪輸出2卿堂,4束莫,3,5草描。

第三輪事件循環(huán)開始览绿,此時只剩setTimeout2了,執(zhí)行穗慕。

直接輸出9饿敲。

將process.nextTick()分發(fā)到微任務(wù)Event Queue中。記為process3逛绵。

直接執(zhí)行new Promise怀各,輸出11。

將then分發(fā)到微任務(wù)Event Queue中术浪,記為then3瓢对。

宏任務(wù)Event Queue微任務(wù)Event Queue

process3

then3

第三輪事件循環(huán)宏任務(wù)執(zhí)行結(jié)束,執(zhí)行兩個微任務(wù)process3和then3胰苏。

輸出10硕蛹。

輸出12。

第三輪事件循環(huán)結(jié)束硕并,第三輪輸出9法焰,11,10倔毙,12埃仪。

整段代碼,共進(jìn)行了三次事件循環(huán)陕赃,完整的輸出為1卵蛉,7,6凯正,8毙玻,2豌蟋,4廊散,3,5梧疲,9允睹,11运准,10,12缭受。

(請注意胁澳,node環(huán)境下的事件監(jiān)聽依賴libuv與前端環(huán)境不完全相同,輸出順序可能會有誤差)



總結(jié)

1.js的異步

js是一門單線程的語言米者,無論是什么新框架新語法實(shí)現(xiàn)的所謂異步韭畸,都是用同步的方法去模擬的

2.事件循環(huán)event? Loop

事件循環(huán)是js實(shí)現(xiàn)異步的一種方法,也是js的執(zhí)行機(jī)制

3.js的執(zhí)行與運(yùn)行

js在不同的環(huán)境下蔓搞,不如node胰丁,瀏覽器等,執(zhí)行方式是不同的

運(yùn)行大多指js解析引擎,是統(tǒng)一的



作者:ssssyoki

鏈接:https://juejin.im/post/59e85eebf265da430d571f89

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末喂分,一起剝皮案震驚了整個濱河市锦庸,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蒲祈,老刑警劉巖甘萧,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異梆掸,居然都是意外死亡扬卷,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進(jìn)店門沥潭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來邀泉,“玉大人,你說我怎么就攤上這事钝鸽』阈簦” “怎么了?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵拔恰,是天一觀的道長因谎。 經(jīng)常有香客問我,道長颜懊,這世上最難降的妖魔是什么财岔? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮河爹,結(jié)果婚禮上匠璧,老公的妹妹穿的比我還像新娘。我一直安慰自己咸这,他們只是感情好夷恍,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著媳维,像睡著了一般酿雪。 火紅的嫁衣襯著肌膚如雪遏暴。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天指黎,我揣著相機(jī)與錄音朋凉,去河邊找鬼。 笑死醋安,一個胖子當(dāng)著我的面吹牛杂彭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播吓揪,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼盖灸,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了磺芭?” 一聲冷哼從身側(cè)響起赁炎,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎钾腺,沒想到半個月后徙垫,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡放棒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年姻报,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片间螟。...
    茶點(diǎn)故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡吴旋,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出厢破,到底是詐尸還是另有隱情荣瑟,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布摩泪,位于F島的核電站笆焰,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏见坑。R本人自食惡果不足惜嚷掠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望荞驴。 院中可真熱鬧不皆,春花似錦、人聲如沸熊楼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至项棠,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間挎峦,已是汗流浹背香追。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留坦胶,地道東北人透典。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像顿苇,于是被迫代替她去往敵國和親峭咒。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評論 2 349

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