首先咱們你們都瞭解的是,JavaScript 是一門單線程語言,因此咱們就能夠得出:java
JavaScript 是按照語句順序執行的面試
首先看:瀏覽器
let a = '1' console.log(a) let b = '2' console.log(b)
這個顯然你們都知道結果,依次輸出1,2多線程
然而換一種:架構
setTimeout(function() { console.log(1) }) new Promise(function(resolve) { console.log(2) for(var i = 0;i< 10;i++){ i === 10 && resolve() } }).then(function() { console.log(3) }) console.log(4)
這個時候再看代碼的順序執行,輸出1,2, 3, 4。好了放到瀏覽器運行一下,什麼?輸出竟然是 2, 4, 3,1。說好的按順序執行呢?下面就須要去了解一下 JavaScript 的執行機制問題了。框架
首先JavaScript 是一門單線程的語言,在最新的HTML5 推出的 Web-worker,可是 JavaScript 是一個單線程的語言這一個核心仍是沒有改變。因此,JavaScript 的多線程都是基於單線程模擬出來的。因此牢記 JavaScript 是單線程語言。異步
任務分爲兩類:分佈式
當咱們打開頁面時,頁面的渲染就是一大堆同步任務,而像加載圖片和音頻資源耗時的任務,就是異步任務。時間循環的主要內容就是:函數
其中js引擎存在一個監控進程,不斷檢查主線程執行棧是否爲空,一旦爲空,就會去時間隊列那檢查有沒有等待被調用的函數。源碼分析
例如:
setTimeout( function() { console.log(1) }, 0) console.log(2)
這也就是爲何即便設置setTimeout(fn, 0)
函數也不會當即執行的緣由。不過即便主線程爲空,0ms也是達不到的,根據HTML標準,最低是4ms。
還有一個與setTimeout
相似的函數,對於setInterval
來講,是循環執行。對於執行順序來講,setInterval
會每隔指定的時間將註冊的函數置入Event Queue,若是前面的任務耗時過久,那麼一樣須要等待。
可是須要注意的一點是,對於setInterval(fn, ms)
來講,他並非每過ms
執行一次 ,而是每過 ms
會有fn
進入任務隊列。也就是說若是setInterval
的回調函數的執行事件若是超過延遲ms
,那麼就看不出來事件間隔了。
除了廣義的同步任務和異步任務以外,還有對任務更精細的劃分,分爲:
事件循環的順序,決定js代碼的執行順序。進入總體代碼(宏任務)後,開始第一次循環。接着執行全部的微任務。而後再次從宏任務開始,找到其中一個任務隊列執行完畢,再執行全部的微任務。
用一段代碼來講明:
setTimeout(function() { console.log('1'); }) new Promise(function(resolve) { console.log('2'); resolve() }).then(function() { console.log('3'); }) console.log('4');
setTimeout
,那麼它的回調函數進入到宏任務事件隊列中Promise
,Promise
當即執行,輸出2,then
任務進入到微任務事件隊列中then
,輸出3好了瞭解了基本的原理以後,咱們來看一個更復雜的:
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') }) })
不知道你們答案是什麼?接下來咱們來進行分析一下:
第一輪:
console.log()
輸出1setTimeout()
進入宏任務隊列Process.nextTick()
進入微任務隊列Promise
,當即執行,輸出7,then
被添加到微任務隊列setTimeout
,進入宏任務隊列Process.nextTick()
輸出6then
,輸出8這樣第一輪循環就完全結束了,進行第二輪事件循環,也就是第一個setTimeout
console.log()
,輸出2Process.nextTick()
,進入微任務隊列Promise
當即執行輸出4,then
進入微任務隊列這樣第二輪事件循環就結束了,最後執行第二個setTimeout
,第二個setTimeout
和上面原理相似,也就不重複說明了。因此最終結果是:1,7,6,8,2,4,3,5,9,11,10,12
加Java架構師羣獲取Java工程化、高性能及分佈式、高性能、深刻淺出。高架構。性能調優、Spring,MyBatis,Netty源碼分析和大數據等多個知識點高級進階乾貨的直播免費學習權限 都是大牛帶飛 讓你少走不少的彎路的 羣..號是:855801563 對了 小白勿進 最好是有開發經驗
注:加羣要求
一、具備工做經驗的,面對目前流行的技術不知從何下手,須要突破技術瓶頸的能夠加。
二、在公司待久了,過得很安逸,但跳槽時面試碰壁。須要在短期內進修、跳槽拿高薪的能夠加。
三、若是沒有工做經驗,但基礎很是紮實,對java工做機制,經常使用設計思想,經常使用java開發框架掌握熟練的,能夠加。
四、以爲本身很牛B,通常需求都能搞定。可是所學的知識點沒有系統化,很難在技術領域繼續突破的能夠加。
5.阿里Java高級大牛直播講解知識點,分享知識,多年工做經驗的梳理和總結,帶着你們全面、科學地創建本身的技術體系和技術認知!