關(guān)于Timer,最核心的api 就是 setTimeout 和 clearTimeout。本文將會以這兩個函數(shù)作為展開來分析node.js 是怎么實現(xiàn)這兩個api。
API
對于setTimout 相信很多人都會覺得很熟悉它的用法,函數(shù)的主要功能是,間隔一定秒數(shù),執(zhí)行回調(diào)函數(shù)。
然而,需要提醒的是,因為很多同學是從前端轉(zhuǎn)過來的,所以會忽略了 在node.js 里面 setTimeout 可以傳參數(shù)的特性
setTimeout(callback, delay[, arg][, ...])
setTimeout(function (a, b) {
console.log(a, b); // 1, 2
}, 100, 1, 2);
實現(xiàn)原理
setTimeout 會創(chuàng)建一個timer對象,timer對象的底層實現(xiàn)由libuv 的 uv_timer_init 負責,檢查是否存在二叉樹,如果二叉樹不存在,創(chuàng)建二叉樹,利用uv_timer_start方法啟動定時器,并將js編寫的回調(diào)的方法綁定到uv_timer_start的回調(diào)事件里,如果二叉樹已經(jīng)存在,并將其插入一個二叉樹里面,二叉樹,是按照定時間隔,從小到大排列。
當 uv_timer_start 到達時間后,將會執(zhí)行創(chuàng)建時候約定好的回調(diào)函數(shù),并查看二叉樹里面,下一個,離現(xiàn)在最近將要執(zhí)行的函數(shù),將其提取,并執(zhí)行uv_timer_start 方法,讓它在過了某一段時間后,執(zhí)行回調(diào)函數(shù),不斷循環(huán)上述過程,直到二叉樹為空,便停止。
setTimeout的實現(xiàn)就告一段落了。
后記
我真的不是故意忘記clearTimeout這個api,而是我覺得真的非常重要,所以才擺到后記位置,前文說了,node.js利用uv_timer_init 創(chuàng)建了timer 結(jié)構(gòu),所以為了讓這個結(jié)構(gòu)對象,釋放內(nèi)存,就必須使用clearTimeout進行銷毀,所以大家在調(diào)用setTimeout 謹記調(diào)用clearTimeout,否則會產(chǎn)生內(nèi)存泄漏。