我很难理解如何正确使用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的例子,这是什么时候需要的?
发布于 2019-01-15 19:09:14
有关HandleScopes是什么及其用途的说明,请参阅V8文档,例如,对于Local类
句柄有两种类型:本地句柄和持久句柄。 本地句柄是重量轻和瞬态的,通常用于本地操作.它们由HandleScopes管理。这意味着当创建HandleScope时,它们必须存在于堆栈中,并且它们仅在创建过程中活动的HandleScope中有效。要将本地句柄传递给外部HandleScope,必须使用EscapableHandleScope及其Escape()方法。
对于HandleScope类
控制许多本地句柄的堆栈分配类。在创建句柄作用域之后,将在该句柄范围内分配所有本地句柄,直到删除句柄作用域或创建另一个句柄范围为止。如果已经有一个句柄作用域并创建了一个新的句柄作用域,那么所有分配都将在新句柄作用域中进行,直到它被删除为止。在此之后,将再次在原始句柄范围中分配新句柄。 在删除了本地句柄的句柄作用域后,垃圾回收器将不再跟踪存储在句柄中的对象,并可能释放它。访问句柄作用域已被删除的句柄的行为未定义。
务实地:
Local<>,那么至少需要一个Local<>。通常正确的数字是一个HandleScope。EscapableHandleScope。发布于 2019-11-03 07:24:20
以下内容似乎适用于nan、nan和节点-addon:
句柄作用域是一种抽象,用于控制和修改在特定范围内创建的对象的生存期。通常,N值是在句柄作用域的上下文中创建的.当从JavaScript调用本机方法时,将存在一个默认句柄作用域。如果用户不显式创建新句柄作用域,则将在默认句柄范围中创建new值。对于本机方法执行之外的任何代码调用(例如,在libuv回调调用期间),模块是必需的,以便在调用任何可能导致创建JavaScript值的函数之前创建作用域。
来源:作用域
这意味着,在给出的示例中,由于两者都是直接从const Napi::CallbackInfo& info调用的,所以它们已经有了JS运行时提供的作用域--只有当您希望自己执行内存管理时,或者在您的代码独立于JS引擎执行的情况下(例如在计时器上,来自于JS代码以外的东西的回调,等等),创建作用域的附加调用才是必要的。
发布于 2020-01-20 07:59:54
为什么我们需要在代码片段中创建一个新的HandleScope?
实际上,我们可以选择在这里不创建一个新的HandleScope。Node.js中有一个外部作用域,它包含在此函数中创建的句柄。但是,在这个函数中创建的所有句柄都会比必要的长,并处理成本资源。
我们什么时候需要EscapableHandleScope?
当来自内部作用域的句柄需要超过该作用域的生存期时。例如,当返回函数中新创建的数据时。
参考文献
V8嵌入:https://v8.dev/docs/embed#handles-and-garbage-collection
节点-addon:management.md
https://stackoverflow.com/questions/54187588
复制相似问题