转自《深入浅出Node.js》
尽管我们在介绍Node的时候,多数情况下都会提到异步I/O,但是Node中其实还存在一些与I/O无关的异步API, 如setTimeout(), setInterval(), setImmediate()和process.nextTick()
定时器:
setTimeout():用于单次定时任务
setInterval():用于多次定时任务
它们的实现原理与异步I/O比较类似,只是不需要I/O线程池的参与。调用setTimeout()或者setInterval()创建的定时器会被插入到定时器观察者内部的一个红黑树中。每次Tick执行时,会从该红黑树中迭代取出定时器对象,检查是否超过定时时间,如果超过,就形成一个事件,它的回调函数将立即执行。
定时器的问题在于它并非精确的。如果在定时到期前其它任务占用了CPU时间片,则会导致定时器计时超过预定时间。比如通过setTimeout()设定一个任务在10毫秒后执行,但是在9毫秒后,有一个任务用了5毫秒的CPU时间片,再次轮到定时器执行时,时间就已经过期4毫秒。
process.nextTick()
process.nextTick(function() {
//Todo用来立即异步执行一个任务
});
setImmediate()中的回调函数执行的优先级低于process.nextTick()
process.nextTick()的回调函数保存在一个数组中,setImmediate()的结果保存在链表中process.nextTick(() => {
console.log('nextTick延迟执行1');
});
process.nextTick(() => {
console.log('nextTick延迟执行2');
});
setImmediate(() => {
console.log('setImmediate延迟执行1');
process.nextTick(() => {
console.log('nextTick延迟执行3');
});
});
setImmediate(() => {
console.log('setImmediate延迟执行2');
});
console.log('正常执行1');
console.log('正常执行2');
输出:
正常执行1
正常执行2
nextTick延迟执行1
nextTick延迟执行2
setImmediate延迟执行1
setImmediate延迟执行2
nextTick延迟执行3