1. 程式人生 > >Node.js中非I/O的非同步API

Node.js中非I/O的非同步API

Node中存在一些與I/O無關的非同步API,分別是setTimeout()、setInterval()、setImmediate()和process.nextTick().

setTimeout()和setInterval()分別用於單次和多次定時執行任務,不需要I/O執行緒池參與,呼叫setTimeout()或setInterval()建立的定時器會被插入到定時器觀察者內部的一個紅黑樹中。每次Tick執行時,會從該紅黑樹中迭代取出定時器物件,檢查是否超過定時時間,如果超過,就形成一個事件,它的回撥函式將立即執行。

定時器的問題在於它並非精確的,儘管事件迴圈十分快,但是如果某一次迴圈佔用的時間較多,那麼下次迴圈時,它也許超時很久了,譬如通過setTimeout()設定一個任務在10ms後執行,但是在9ms後,有一個任務佔用了5ms的CPU時間,再次輪到定時器任務時,時間就已經過期4ms。

 

在未了解process.nextTick()之前,很多人也許為了立即非同步執行一個任務,會呼叫setTime(fn,0)來達到所需的效果。

由於事件迴圈自身的特點,定時器的精度不夠,而事實上,採用定時器需要動用紅黑樹,建立定時器物件和迭代等操作,而setTimeout()的方式較為浪費效能,process.nextTick()方法的操作較為輕量,每次呼叫process.nextTick()方法,只會將回調函式放入佇列中,在下一輪tick時取出執行。

setImmediate()方法和process.nextTick()類似,都是將回調函式延遲執行,但是process.nextTick中的回撥函式的優先順序要高於setImmediate,這是因為事件迴圈對觀察者的檢查是有先後順序的,process.nextTick()屬於idle觀察者,setImmediate屬於check觀察者,在每一輪迴圈檢查中,idle觀察者優選與I/O觀察者,I/O觀察者優先於check觀察者。