了解节点附加API(N-API)HandleScope

时间:2019-01-14 19:01:38

标签: node.js nan v8 node.js-addon

我很难理解如何正确使用HandleScopeEscapableHandleScope。例如,来自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找不到任何示例?

2 个答案:

答案 0 :(得分:1)

有关什么是HandleScopes及其用途的解释,请参见V8's documentation,例如对于课程Local

  

有两种类型的句柄:本地句柄和持久句柄。

     

本地手柄轻巧且瞬变,通常用于   本地操作。它们由HandleScopes管理。这意味着   创建它们时,HandleScope必须存在于堆栈中,并且它们仅在其运行期间处于活动的HandleScope内部有效   创建。要将本地句柄传递到外部HandleScope,   必须使用EscapableHandleScope及其Escape()方法。

对于类HandleScope

  

管理多个本地句柄的堆栈分配类。后   一个句柄作用域已创建,将分配所有本地句柄   在该句柄范围内,直到删除该句柄范围或   创建另一个句柄作用域。如果已经有一个句柄范围   并创建一个新的,所有分配将在新   处理范围,直到将其删除。之后,新的手柄将再次出现   在原始句柄范围内分配。

     

删除本地句柄的句柄范围后,垃圾   收集器将不再跟踪存储在句柄中的对象,并且可能   取消分配它。访问句柄的行为   句柄范围已删除是不确定的。

实用:

  • 从JavaScript调用C ++时,如果C ++代码创建了任何HandleScope,则至少需要一个Local<>。通常,恰好一个HandleScope是正确的数字。
  • 创建和销毁HandleScopes会产生一定的成本,因此,如果您有许多细粒度的HandleScopes,那是在浪费时间。另一方面,HandleScope(按设计,这就是它的目的!)使其中包含的句柄所引用的所有对象保持活动状态(从GC角度而言),因此对于运行时间很长的代码或循环多次迭代而言,您可能要引入短暂的HandleScopes,以便可以释放完成的临时对象。
  • 如文档所述,如果要在范围的生存期结束后返回对象,则需要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代码以外的其他地方进行回调等)