您好,登錄后才能下訂單哦!
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里掛載了一個基于堆結構體。當結束監聽的時候,他需要釋放掉這塊內存。
// 停止poll
int 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實現事件循環的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。