使句柄寿命短于本地方法


¥Making handle lifespan shorter than that of the native method

通常需要使句柄的生命周期短于本地方法的生命周期。例如,考虑一个本地方法,它有一个循环遍历大型数组中的元素:

¥It is often necessary to make the lifespan of handles shorter than the lifespan of a native method. For example, consider a native method that has a loop which iterates through the elements in a large array:

for (int i = 0; i < 1000000; i++) {
  napi_value result;
  napi_status status = napi_get_element(env, object, i, &result);
  if (status != napi_ok) {
    break;
  }
  // do something with element
} 

这将导致创建大量句柄,消耗大量资源。此外,即使原生代码只能使用最近的句柄,所有关联的对象也将保持活动状态,因为它们都共享相同的范围。

¥This would result in a large number of handles being created, consuming substantial resources. In addition, even though the native code could only use the most recent handle, all of the associated objects would also be kept alive since they all share the same scope.

为了处理这种情况,Node-API 提供了建立新的 'scope' 的能力,新创建的句柄将与之关联。一旦不再需要这些句柄,范围可以是 'closed',并且与该范围关联的任何句柄都将失效。可用于打开/关闭范围的方法是 napi_open_handle_scopenapi_close_handle_scope

¥To handle this case, Node-API provides the ability to establish a new 'scope' to which newly created handles will be associated. Once those handles are no longer required, the scope can be 'closed' and any handles associated with the scope are invalidated. The methods available to open/close scopes are napi_open_handle_scope and napi_close_handle_scope.

Node-API 仅支持单个嵌套的范围层次结构。任何时候都只有一个活动范围,所有新句柄都将与该范围关联,同时它处于活动状态。必须按照打开范围的相反顺序关闭范围。此外,在从该方法返回之前,必须关闭在原生方法中创建的所有作用域。

¥Node-API only supports a single nested hierarchy of scopes. There is only one active scope at any time, and all new handles will be associated with that scope while it is active. Scopes must be closed in the reverse order from which they are opened. In addition, all scopes created within a native method must be closed before returning from that method.

以前面的例子为例,添加对 napi_open_handle_scopenapi_close_handle_scope 的调用将确保在整个循环执行过程中最多只有一个句柄有效:

¥Taking the earlier example, adding calls to napi_open_handle_scope and napi_close_handle_scope would ensure that at most a single handle is valid throughout the execution of the loop:

for (int i = 0; i < 1000000; i++) {
  napi_handle_scope scope;
  napi_status status = napi_open_handle_scope(env, &scope);
  if (status != napi_ok) {
    break;
  }
  napi_value result;
  status = napi_get_element(env, object, i, &result);
  if (status != napi_ok) {
    break;
  }
  // do something with element
  status = napi_close_handle_scope(env, scope);
  if (status != napi_ok) {
    break;
  }
} 

嵌套作用域时,有时内部作用域的句柄需要超出该作用域的生命周期。Node-API 支持 '可转义的范围' 以支持这种情况。可转义作用域允许一个句柄为 'promoted',以便 'escapes' 当前作用域和句柄的生命周期从当前作用域变为外部作用域。

¥When nesting scopes, there are cases where a handle from an inner scope needs to live beyond the lifespan of that scope. Node-API supports an 'escapable scope' in order to support this case. An escapable scope allows one handle to be 'promoted' so that it 'escapes' the current scope and the lifespan of the handle changes from the current scope to that of the outer scope.

可用于打开/关闭可转义范围的方法是 napi_open_escapable_handle_scopenapi_close_escapable_handle_scope

¥The methods available to open/close escapable scopes are napi_open_escapable_handle_scope and napi_close_escapable_handle_scope.

提升句柄的请求是通过 napi_escape_handle 触发的,只能调用一次。

¥The request to promote a handle is made through napi_escape_handle which can only be called once.