你們都知道,javascript是一門單線程語言,所以爲了實現主線程的不阻塞,Event Loop這樣的方案應運而生。javascript
瀏覽器和node中Event loop並不同,瀏覽器的Event loop是在HTML5中定義的規範,而node中則由libuv庫實現。java
瀏覽器中的Event loopnode
主線程以外,還存在一個任務隊列。promise
整個最基本的Event Loop如圖所示:瀏覽器
具體過程:異步
整個的這種運行機制又稱爲Event Loop(事件循環)socket
例子oop
瞭解瀏覽器的Event loop後,查看下面例子,猜想瀏覽器是怎麼輸出的ui
console.log(1); console.log(2); setTimeout(function(){ console.log('setTimeout1'); Promise.resolve().then(function(){ console.log('Promise') }) }) setTimeout(function(){ console.log('setTimeout2'); }) //瀏覽器輸出:1 2 setTimeout1 Promise setTimeout2
node中的Event loopthis
例子
查看下面例子加深對event loop的理解
在node執行下面代碼,發現每次執行前後順序不同,由於node須要啓動時間,執行過程當中setTimeout可能到時間了也可能沒到時間,因此這個前後順序取決於node的執行時間。
setTimeout(function(){ console.log('timeout') }) setImmediate(function(){ console.log('immediate') })
i/o操做階段完成後,會走check階段,因此setImmediate會優先走
let fs=require('fs'); fs.readFile('./1.log',function(){ console.log('fs'); setTimeout(function(){ console.log('timeout') }) setImmediate(funciton(){ console.log('setTimmediate') }) })
nextTick應用場景
function Fn(){ this.arrs; process.nextTick(()=>{ //根據nextTick的特性,能夠先賦值,再在下一個隊列中使用 this.arrs(); }) } Fn.prototype.then=function(){ this.arrs=function(){console.log(1)} } let fn=new Fn(); fn.then(); //注意:nextTick千萬不要寫遞歸,否則會形成死循環。能夠放一些比setTimeout優先執行的任務
總結