Node.js中的Timers模塊包含在一段時間後執行代碼的函數,定時器不須要經過require()
導入,由於全部方法均可以在全局範圍內模擬瀏覽器JavaScript API,要徹底瞭解什麼時候執行定時器功能,最好先閱讀Node.js事件循環。segmentfault
Node.js API提供了幾種調度代碼的方法,以便在當前時刻以後的某個時刻執行,下面的函數可能看起來很熟悉,由於它們在大多數瀏覽器中均可用,但Node.js實際上提供了這些方法的本身的實現,定時器與系統緊密集成,儘管API鏡像了瀏覽器API,但實現方面存在一些差別。瀏覽器
setTimeout()
setTimeout()
可用於在指定的毫秒數後調度代碼執行,此函數相似於瀏覽器JavaScript API中的window.setTimeout(),可是沒法傳遞一串代碼來執行。ide
setTimeout()
接受一個函數做爲第一個參數執行,毫秒延遲定義爲一個數字做爲第二個參數,還能夠包括其餘參數,並將這些參數傳遞給函數,這是一個例子:函數
function myFunc(arg) { console.log(`arg was => ${arg}`); } setTimeout(myFunc, 1500, 'funky');
因爲調用了setTimeout()
,上面的函數myFunc()
將盡量接近1500毫秒(或1.5秒)執行。性能
設置的超時間隔不能依賴於在該精確的毫秒數以後執行,這是由於阻塞或保留在事件循環上的其餘執行代碼將推遲執行超時,惟一的保證是超時不會比聲明的超時間隔更早執行。ui
setTimeout()
返回一個Timeout
對象,該對象可用於引用已設置的超時,此返回的對象可用於取消超時(請參閱下面的clearTimeout()
)以及更改執行行爲(請參閱下面的unref()
)。this
setImmediate()
setImmediate()
將在當前事件循環週期結束時執行代碼,此代碼將在當前事件循環中的任何I/O操做以後以及爲下一個事件循環調度的任何計時器以前執行,這個代碼執行能夠被認爲是「正好在此以後」,這意味着setImmediate()
函數調用以後的任何代碼都將在setImmediate()
函數參數以前執行。code
setImmediate()
的第一個參數將是要執行的函數,任何後續參數將在執行時傳遞給函數,這是一個例子:對象
console.log('before immediate'); setImmediate((arg) => { console.log(`executing immediate: ${arg}`); }, 'so immediate'); console.log('after immediate');
傳遞給setImmediate()
的上述函數將在全部可運行代碼執行後執行,控制檯輸出將爲:進程
before immediate after immediate executing immediate: so immediate
setImmediate()
返回一個Immediate
對象,可用於取消已調度的immediate(請參閱下面的clearImmediate()
)。
注意:不要混淆setImmediate()
和process.nextTick()
,它們有一些主要的不一樣之處,第一個是process.nextTick()
將在任何設置的Immediate
以前以及任何調度的I/O以前運行,第二個是process.nextTick()
是不可清除的,意思是一旦代碼被安排用process.nextTick()
執行,就沒法中止執行,就像使用普通函數同樣,請參閱本指南以更好地理解process.nextTick()
的操做。
setInterval()
若是存在應該屢次執行的代碼塊,則可使用setInterval()
來執行該代碼,setInterval()
接受一個函數參數,它將以給定的毫秒延遲做爲第二個參數運行無限次,就像setTimeout()
同樣,能夠在延遲以外添加其餘參數,並將這些參數傳遞給函數調用。也像setTimeout()
同樣,因爲可能保留在事件循環上的操做,所以沒法保證延遲,所以應將其視爲近似延遲,見下面的例子:
function intervalFunc() { console.log('Cant stop me now!'); } setInterval(intervalFunc, 1500);
在上面的例子中,intervalFunc()
大約每1500毫秒或1.5秒執行一次,直到它被中止爲止(見下文)。
與setTimeout()
同樣,setInterval()
也返回一個Timeout
對象,該對象可用於引用和修改已設置的間隔。
若是須要取消Timeout
或Immediate
對象,能夠作些什麼?setTimeout()
、setImmediate()
和setInterval()
返回一個可用於引用設置Timeout
或Immediate
對象的計時器對象,經過將所述對象傳遞到相應的clear
函數,將徹底中止該對象的執行。相應的函數是clearTimeout()
,clearImmediate()
和clearInterval()
,請參閱下面的示例,瞭解每一個示例:
const timeoutObj = setTimeout(() => { console.log('timeout beyond time'); }, 1500); const immediateObj = setImmediate(() => { console.log('immediately executing immediate'); }); const intervalObj = setInterval(() => { console.log('interviewing the interval'); }, 500); clearTimeout(timeoutObj); clearImmediate(immediateObj); clearInterval(intervalObj);
請記住,setTimeout
和setInterval
返回Timeout
對象,Timeout
對象提供了兩個函數,旨在使用unref()
和ref()
來加強Timeout
行爲。若是使用set
函數調度Timeout
對象,則能夠在該對象上調用unref()
,這將稍微改變行爲,若是它是要執行的最後一個代碼,則不會調用Timeout
對象,Timeout
對象不會使進程保持活動狀態,等待執行。
以相似的方式,調用了unref()
的Timeout
對象能夠經過在同一個Timeout
對象上調用ref()
來刪除該行爲,而後確保其執行。但請注意,出於性能緣由,這並不能徹底恢復初始行爲,請參閱如下兩個示例:
const timerObj = setTimeout(() => { console.log('will i run?'); }); // if left alone, this statement will keep the above // timeout from running, since the timeout will be the only // thing keeping the program from exiting timerObj.unref(); // we can bring it back to life by calling ref() inside // an immediate setImmediate(() => { timerObj.ref(); });
事件循環和計時器比本指南所涵蓋的要多得多,要了解有關Node.js事件循環內部以及計時器在執行期間如何操做的更多信息,請查看此Node.js指南:Node.js事件循環、定時器和process.nextTick()。