我很难理解如何正确使用HandleScope和EscapableHandleScope。例如,来自this Node example:
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?然后从this other example:
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找不到任何示例?
答案 0 :(得分:1)
有关什么是HandleScopes及其用途的解释,请参见V8's documentation,例如对于课程Local
:
有两种类型的句柄:本地句柄和持久句柄。
本地手柄轻巧且瞬变,通常用于 本地操作。它们由HandleScopes管理。这意味着 创建它们时,HandleScope必须存在于堆栈中,并且它们仅在其运行期间处于活动的HandleScope内部有效 创建。要将本地句柄传递到外部HandleScope, 必须使用EscapableHandleScope及其Escape()方法。
对于类HandleScope
:
管理多个本地句柄的堆栈分配类。后 一个句柄作用域已创建,将分配所有本地句柄 在该句柄范围内,直到删除该句柄范围或 创建另一个句柄作用域。如果已经有一个句柄范围 并创建一个新的,所有分配将在新 处理范围,直到将其删除。之后,新的手柄将再次出现 在原始句柄范围内分配。
删除本地句柄的句柄范围后,垃圾 收集器将不再跟踪存储在句柄中的对象,并且可能 取消分配它。访问句柄的行为 句柄范围已删除是不确定的。
实用:
HandleScope
,则至少需要一个Local<>
。通常,恰好一个HandleScope
是正确的数字。EscapableHandleScope
。答案 1 :(得分:0)
以下内容似乎适用于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代码以外的其他地方进行回调等)