如何正确使用Nan::HandleScope?
How to properly use Nan::HandleScope?
我正在使用 NAN 为节点编写一个 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() 调用,returns json 对象是由 TreeNode class 创建。这个对吗?或者我应该在调用 Nan::New 的所有地方使用 HandleScope 吗?或者它也应该使用 EscapableHandleScope 而不是 HandleScope 因为我实际上想返回生成的值?
直接取自文档降价:
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,但应该在函数需要 return 已在其中创建的 V8 JavaScript 类型的情况下使用。
因此,您在 App::getData()
中使用 Nan::EscapableHandleScope
是正确的。但是,我认为 App::getData()
中的 Nan::EscapableHandleScope
可以移动到 TreeNode::getData( const TreeNode* pNode )
,因为这是实际创建 V8 Javascript 类型的函数。
我认为你在这里所做的没有任何问题,我只是倾向于让 Nan::HandleScope
/ Nan::EscapableHndleScope
更接近(最好在)创建对象的函数returned.
我正在使用 NAN 为节点编写一个 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() 调用,returns json 对象是由 TreeNode class 创建。这个对吗?或者我应该在调用 Nan::New 的所有地方使用 HandleScope 吗?或者它也应该使用 EscapableHandleScope 而不是 HandleScope 因为我实际上想返回生成的值?
直接取自文档降价:
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,但应该在函数需要 return 已在其中创建的 V8 JavaScript 类型的情况下使用。
因此,您在 App::getData()
中使用 Nan::EscapableHandleScope
是正确的。但是,我认为 App::getData()
中的 Nan::EscapableHandleScope
可以移动到 TreeNode::getData( const TreeNode* pNode )
,因为这是实际创建 V8 Javascript 类型的函数。
我认为你在这里所做的没有任何问题,我只是倾向于让 Nan::HandleScope
/ Nan::EscapableHndleScope
更接近(最好在)创建对象的函数returned.