Nodejs的特點是事件驅動,異步I/O產生的高並發,產生此特點的引擎是事件循環,事件被分門別類地歸到對應的事件觀察者上,比如idle觀察者,定時器觀察者,I/O觀察者等等,事件循環每次循環稱為Tick,每次Tick按照先后順序從事件觀察者中取出事件進行處理。
調用setTimeout()或setInterval()時創建的計時器會被放入定時器觀察者內部的紅黑樹中,每次Tick時,會從該紅黑樹中檢查定時器是否超過定時時間,超過的話,就立即執行對應的回調函數。setTimeout()和setInterval()都是當定時器使用,他們的區別在於后者是重復觸發,而且由於時間設的過短會造成前一次觸發后的處理剛完成后一次就緊接着觸發。
由於定時器是超時觸發,這會導致觸發精確度降低,比如用setTimeout設定的超時時間是5秒,當事件循環在第4秒循到了一個任務,它的執行時間3秒的話,那么setTimeout的回調函數就會過期2秒執行,這就是造成精度降低的原因。並且由於采用紅黑樹和迭代的方式保存定時器和判斷觸發,較為浪費性能。
使用process.nextTick()所設置的所有回調函數都會放置在數組中,會在下一次Tick時所有的都立即被執行,該操作較為輕量,時間精度高。
setImmediate()設置的回調函數也是在下一次Tick時被調用,其和process.nextTick()的區別在於兩點:
1.他們所屬的觀察者被執行的優先級不一樣,process.nextTick()屬於idle觀察者,setImmediate()屬於check觀察者,idle的優先級>check。
2.setImmediate()設置的回調函數是放置在一個鏈表中,每次Tick只執行鏈表中的一個回調。這是為了保證每次Tick都能快速地被執行。