温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

nodejs中怎么利用close实现事件循环

发布时间:2021-07-21 09:05:47 阅读:151 作者:Leah 栏目:大数据
前端开发者测试专用服务器限时活动,0元免费领,库存有限,领完即止! 点击查看>>

nodejs中怎么利用close实现事件循环,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

close是nodejs每轮事件循环中最后的一个阶段。我们看看怎么使用。我们知道对于一个handle,他的使用一般是init,start,stop。但是如果我们在stop一个handle之后,还有些事情需要处理怎么办?这时候就可以使用close阶段。close阶段可以用来关闭一个handle,并且执行一个回调。比如用于释放动态申请的内存。close阶段的任务由uv_close产生。

void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {  // 正在关闭,但是还没执行回调等后置操作  handle->flags |= UV_HANDLE_CLOSING;  handle->close_cb = close_cb;  switch (handle->type) {  case UV_PREPARE:    uv__prepare_close((uv_prepare_t*)handle);    break;  case UV_CHECK:    uv__check_close((uv_check_t*)handle);    break;    ...  default:    assert(0);  }  uv__make_close_pending(handle);}
 

uv_close设置回调和状态,然后根据handle类型调对应的close函数,一般就是stop这个handle。比如prepare的close函数。

void uv__prepare_close(uv_prepare_t* handle) {                               uv_prepare_stop(handle);                                                 }
 

接着执行uv__make_close_pending往close队列追加节点。

// 头插法插入closing队列,在closing阶段被执行void uv__make_close_pending(uv_handle_t* handle) {  handle->next_closing = handle->loop->closing_handles;  handle->loop->closing_handles = handle;}
 

产生的节点在closing_handles队列中保存,然后在close节点逐个处理。

// 执行closing阶段的的回调static void uv__run_closing_handles(uv_loop_t* loop) {  uv_handle_t* p;  uv_handle_t* q;  p = loop->closing_handles;  loop->closing_handles = NULL;  while (p) {    q = p->next_closing;    uv__finish_close(p);    p = q;  }}// 执行closing阶段的回调static void uv__finish_close(uv_handle_t* handle) {  handle->flags |= UV_HANDLE_CLOSED;  ...  uv__handle_unref(handle);  QUEUE_REMOVE(&handle->handle_queue);  if (handle->close_cb) {    handle->close_cb(handle);  }}
 

逐个执行回调,close和stop有一点不同的是,stop一个handle,他不会从事件循环中被移除,但是close一个handle,他会从事件循环的handle队列中移除。
    我们看一个使用了uv_close的例子(省略部分代码)。

int uv_fs_poll_start(uv_fs_poll_t* handle,                     uv_fs_poll_cb cb,                     const char* path,                     unsigned int interval) {  struct poll_ctx* ctx;  // 分配一块堆内存存上下文结构体和path对应的字符串  ctx = uv__calloc(1, sizeof(*ctx) + len);  // 挂载上下文到handle  handle->poll_ctx = ctx;}
 

uv_fs_poll_start是用于监听文件是否有改变的函数。他在handle里挂载了一个基于堆结构体。当结束监听的时候,他需要释放掉这块内存。

// 停止pollint uv_fs_poll_stop(uv_fs_poll_t* handle) {  struct poll_ctx* ctx;  ctx = handle->poll_ctx;  handle->poll_ctx = NULL;  uv_close((uv_handle_t*)&ctx->timer_handle, timer_close_cb);}
 

uv_fs_poll_stop通过uv_close函数关闭handle,传的回调是timer_close_cb。

// 释放上下文结构体的内存static void timer_close_cb(uv_handle_t* handle) {  uv__free(container_of(handle, struct poll_ctx, timer_handle));}
 

所以在close阶段就会是否这块内存。

看完上述内容,你们掌握nodejs中怎么利用close实现事件循环的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注亿速云行业资讯频道,感谢各位的阅读!

亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

原文链接:https://my.oschina.net/u/4217331/blog/4379095

AI

开发者交流群×