![](/img/trans.png)
[英]NODE N-API When using functions from addon blocks the main process node js?
[英]Understanding Node Addon API (N-API) HandleScope
我很難理解如何正確使用HandleScope和EscapableHandleScope 。 例如,從這個節點示例:
MyObject::MyObject(const Napi::CallbackInfo& info) : Napi::ObjectWrap<MyObject>(info) {
Napi::Env env = info.Env();
Napi::HandleScope scope(env);
this->val_ = info[0].As<Napi::Number>().DoubleValue();
};
為什么在這種情況下我們需要創建一個新的 HandleScope ? 從這個另一個例子:
Napi::Object CreateObject(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
Napi::Object obj = Napi::Object::New(env);
obj.Set(Napi::String::New(env, "msg"), info[0].ToString());
return obj;
}
為什么這里不需要?
另外,我沒有找到任何使用 EscapableHandleScope 的例子,什么時候需要這個?
以下似乎適用於 nan、N-API 和 node-addon-api:
[Handle Scope] 是一種抽象,用於控制和修改在特定范圍內創建的對象的生命周期。 通常,N-API 值是在句柄范圍的上下文中創建的。 當從 JavaScript 調用本機方法時,將存在默認句柄范圍。 如果用戶未明確創建新的句柄范圍,則將在默認句柄范圍中創建 N-API 值。 對於本地方法執行之外的任何代碼調用(例如,在 libuv 回調調用期間),模塊需要在調用任何可能導致創建 JavaScript 值的函數之前創建一個范圍。
來源: https : //nodejs.org/api/n-api.html#n_api_napi_handle_scope
這意味着在給出的示例中,由於兩者都期望const Napi::CallbackInfo& info
很明顯兩者都是從 JavaScript 直接調用的,因此它們已經具有由 JS 運行時提供的作用域——僅在需要時才需要額外調用創建作用域自己執行內存管理,或者在您的代碼獨立於 JS 引擎執行的情況下(例如在計時器上,來自 JS 代碼以外的其他東西的回調等)
有關 HandleScopes 是什么以及它們的用途的解釋,請參閱V8 的文檔,例如類Local
:
有兩種類型的句柄:本地句柄和持久句柄。
本地句柄是輕量級和瞬態的,通常用於本地操作。 它們由 HandleScopes 管理。 這意味着 HandleScope 在創建時必須存在於堆棧中,並且它們僅在創建期間處於活動狀態的 HandleScope 內有效。 要將本地句柄傳遞給外部 HandleScope,必須使用 EscapableHandleScope 及其 Escape() 方法。
對於類HandleScope
:
管理多個本地句柄的堆棧分配類。 創建句柄范圍后,將在該句柄范圍內分配所有本地句柄,直到刪除該句柄范圍或創建另一個句柄范圍。 如果已經有一個句柄作用域並且創建了一個新的句柄作用域,則所有分配都將在新的句柄作用域中進行,直到它被刪除。 之后,新的句柄將再次在原始句柄范圍內分配。
刪除本地句柄的句柄范圍后,垃圾收集器將不再跟蹤存儲在句柄中的對象,並可能將其解除分配。 訪問已刪除句柄范圍的句柄的行為是未定義的。
務實:
Local<>
s,則至少需要一個HandleScope
。 通常正好一個HandleScope
是正確的數字。EscapableHandleScope
。其實這里我們可以選擇不創建新的 HandleScope 。 Node.js 中有一個外部作用域,它包含在此函數中創建的句柄。 但是,在此函數中創建的所有句柄將比所需的壽命更長,並處理成本資源。
當來自內部作用域的句柄需要超過該作用域的生命周期時。 例如,當返回函數中新創建的數據時。
V8 嵌入: https : //v8.dev/docs/embed#handles-and-garbage-collection
node-addon-api: https://github.com/nodejs/node-addon-api/blob/master/doc/object_lifetime_management.md
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.