timer 的 unref 函数
发布于 9 年前 作者 alsotang 16260 次预览 最后一次回复是 6 年前 来自 分享
我看遍了所有中文资料的 unref 资料,发现全是错的。。也是醉了。
官方文档:https://nodejs.org/dist/latest-v5.x/docs/api/timers.html#timers_unref
来自:http://www.jb51.net/article/57861.htm
如果这个引用正确的话,那么《Node.js权威指南》这本书里的解释也是错的。
网上大部分的说法都说 unref 会暂停一个回调函数的调用,可实测的代码如下
var timer = setInterval(function () {
console.log(new Date, 1)
}, 1000)
var timer2 = setInterval(function () {
console.log(new Date, 2)
}, 1000)
timer2.unref()
timer2 始终没有被暂停。
按我对于文档的理解,unref 的意思只是让 timer 不会阻止 node 进程的退出,类似垃圾回收时候的引用计数-1的感觉。但不管是否调用了 unref,回调函数都会一直运行。
为了搜索引擎能过来,我堆点关键词:
javascript中setTimeout和setInterval的unref()和ref()
nodejs中的全局函数setTimeout/clearTimeout,setInterval/clearInterval,unref/ref
16 回复
6666
取消不是 clearTimeout / clearInterval 么~哈哈
你上面的匿名函数是不行,但写成这种是可以的 var testFunction=function(){
}
var timer=setInterval(testFunction,1000);
timer.unref();//取消setTimeout和setInterval的调用
timer.ref();//恢复setTimeout和setInterval的调用 unref取消的是它调用的函数
@jiangliqin
你真的跑过?
@alsotang 根据你提供的官网文档, 这个地方
but if it is the only item left in the event loop, it won't keep the program running指明如果调用了unref函数的定时器在事件循环中是仅存在的一个, 那么程序不会继续运行下去, 测试了下:函数中a处如果被注释掉, 此时相当于事件循环队列中只有一个timer2因此程序退出,如果把a处的setInterval换成setTimeout即让timer也仅运行一次, 那么timer和timer2都只会允许一次, 我理解的是timer 在的时候timer2在事件队列中不是唯一的因此它会继续执行.然而如果不调用
unref函数不管怎么样程序都会一直运行下去针对handle而言,判断loop是否存活只要看loop->active_handles是否大于0,大于0则存活。
具体代码参看 https://github.com/libuv/libuv/blob/v1.x/src/uv-common.h
uv__handle_init, uv__handle_start, uv__handle_stop, uv__handle_ref, uv__handle_unref
比较下面几种情况,可能会有利于理解unref的作用。
第一种
第二种
第三种
第四种
第五种
@jiangliqin
@alsotang 和 @ncuzp 的理解是正确的,主要还是看循环是否结束,循环结束了,进程退出了,回调函数当然不会执行了。
uv__hanlde_init(handle) => handle->flags = UV__HANDLE_REF
uv__handle_unref(handle) 清除 handle->flags上的UV__HANDLE_REF位,没有被ref标记位,uv__handle_start(handle), uv__handle_stop(handle) 就不会影响loop->active_handles。
一些文章要么是错的,要么是过时的,最好还是直接去看源代码。https://github.com/libuv/libuv/blob/v1.x/src/uv-common.h
@coordcn 受教
@coordcn 赞
@coordcn 受教
@coordcn 受教
学习了~~
@coordcn 666,涨知识
@coordcn 向大神学习,感叹知道的好少
@coordcn 学习了,看了express-rate-limit这个中间件的实现 ,里面有用到unref,当时也不理解。 ‘use strict’; function MemoryStore(windowMs) { var hits = {};
专门注册一个账号膜拜大佬~~