javascript - 如何正确使用 Nan::HandleScope?

标签 javascript c++ node.js native abstraction

我正在使用 NAN 为 Node 编写一个 C++ 插件,但我对如何正确使用 Nan::HandleScope ( https://github.com/nodejs/nan/blob/master/doc/scopes.md#api_nan_handle_scope) 感到困惑

在我的应用程序中,我正在做这样的事情(删除了错误检查,并且只显示了简化版本的代码):

static App* s_pApp = nullptr;

NAN_METHOD( init ) {
  s_pApp = new App();
} 

NAN_METHOD( getData ) {
  info.GetReturnValue().Set( s_pApp->getData() );
}

NAN_METHOD( close ) {
  delete s_pApp;
  s_pApp = nullptr;
}

//-------- This create a new json object based on the current state of _pRootNode which is a TreeNode class object previously populated
v8::Local<v8::Object> App::getData() const {
    Nan::EscapableHandleScope scope;
    v8::Local<v8::Object> obj = _pRootNode->getData();
    return scope.Escape( obj ); 
}

//-------- The TreeNode class 
v8::Local<v8::Object> TreeNode::getData() const {
  return getData( this );
}

//each node contains data plus a vector of children that are also TreeNodes
v8::Local<v8::Object> TreeNode::getData( const TreeNode* pNode ) const {
  v8::Local<v8::Object> jsonObject = Nan::New<v8::Object>();

  addProperty( jsonObject, "isImportant", _isImportant );
  addProperty( jsonObject, "value", _value );
  addProperty( jsonObject, _children );

  return jsonObject;
}

//The addProperty functions are used to populate the jsonObject which will eventually be returned back to JavaScript
template<class T>
void TreeNode::addProperty( v8::Local<v8::Object>& jsonObject, const char* szName, T propValue ) {
  v8::Local<v8::String> prop = Nan::New( szName ).ToLocalChecked();
  v8::Local<v8::Value> value = getValue( propValue ); //returns the appropriate v8 value
  Nan::Set( jsonObject, prop, value );  
}

void TreeNode::addProperty( v8::Local<v8::Object>& jsonObject, const std::vector<const TreeNode*>& children ) {
  if( children.empty() ) {
    return;
  }

  v8::Local<v8::String> prop = Nan::New( "children" ).ToLocalChecked();

  v8::Local<v8::Array> values = Nan::New<v8::Array>( children.size() );
  for( int i = 0, numChildren = children.size(); i < numChildren; ++i ) {
    values->Set( i, children.at( i )->getData() ); //recursive call
  }

  Nan::Set( jsonObject, prop, values );  
}

正如我们在上面的代码中看到的,我处理范围的唯一地方是在 App::getData() 调用中,它返回由 TreeNode 类创建的 json 对象。它是否正确?或者我应该在调用 Nan::New 的所有地方使用 HandleScope 吗?或者它也应该使用 EscapableHandleScope 而不是 HandleScope 因为我实际上想要返回生成的值?

最佳答案

直接取自文档 Markdown :

Nan::HandleScope - https://github.com/nodejs/nan/blob/master/doc/scopes.md#api_nan_handle_scope :

每当您创建新的 V8 JavaScript 对象时,分配一个新的 Nan::HandleScope。请注意,在 JavaScript 可访问的方法上为您创建了一个隐式 HandleScope,因此您无需自行插入。

Nan::EscapableHandleScope - https://github.com/nodejs/nan/blob/master/doc/scopes.md#api_nan_escapable_handle_scope

类似于 Nan::HandleScope,但应该在函数需要返回已在其中创建的 V8 JavaScript 类型的情况下使用。


因此,您在 App::getData() 中使用 Nan::EscapableHandleScope 是正确的。但是,我认为 App::getData() 中的这个 Nan::EscapableHandleScope 可以移动到 TreeNode::getData( const TreeNode* pNode ),因为这是实际创建 V8 Javascript 类型的函数。

我认为您在这里所做的没有任何问题,我只是倾向于让 Nan::HandleScope/Nan::EscapableHndleScope 更接近 (最好在)创建返回对象的函数中。

关于javascript - 如何正确使用 Nan::HandleScope?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47757310/

相关文章:

javascript - 无法让 DataTables 与 Jade 一起使用

javascript - Jquery - 追加在 html 中显示双引号

javascript - 如何在 Shiny 应用程序中嵌入 Twitter 时间线

javascript - 单击后悬停状态卡在按钮上

c++ - 辅助函数 : lambdas vs normal functions

javascript - Node.js - 向 child_process 发送大对象很慢

javascript - 新的网络打印解决方案

c++ - 表达式 sfinae 中的惯用回退

c++ - 不可预测的输出

javascript - 在 NodeJS 中,如何在不手动添加换行符的情况下将行打印到文件中?