Как правильно использовать Nan::HandleScope?

Я пишу аддон C++ для узла, использующего NAN, но я не совсем понимаю, как правильно использовать 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(), который возвращает объект json, созданный классом TreeNode. Это правильно? Или я должен использовать HandleScope везде, где называется Nan::New? Или он также должен использовать EscapableHandleScope, а не HandleScope, так как я на самом деле хочу вернуть сгенерированные значения?

1 ответ

Решение

Взятые прямо из документации по уценке:

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

Выделяйте новый Nan::HandleScope каждый раз, когда вы создаете новые объекты JavaScript V8. Обратите внимание, что неявный HandleScope создан для вас с помощью доступных JavaScript-методов, поэтому вам не нужно вставлять его самостоятельно.

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

Аналогичен Nan::HandleScope, но должен использоваться в тех случаях, когда функция должна возвращать тип JavaScript V8, созданный в ней.


Итак, вы были правы в использовании Nan::EscapableHandleScope в App::getData(), Тем не менее, я думаю, что это Nan::EscapableHandleScope в App::getData() может быть перемещен в TreeNode::getData( const TreeNode* pNode ), поскольку это функция, которая на самом деле создает тип Vav Javascript.

Я не думаю, что есть что-то не так с тем, что вы сделали здесь, я просто хотел бы сохранить Nan::HandleScope / Nan::EscapableHndleScope ближе (предпочтительно внутри) к функции, которая создает возвращаемый объект.

Другие вопросы по тегам