使句柄寿命短于本地方法


【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 提供了建立一个新的“作用域”的能力,新创建的句柄将与该作用域关联。一旦这些句柄不再需要,该作用域可以被“关闭”,与该作用域关联的任何句柄都会失效。用于打开/关闭作用域的方法是 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 支持“可逃逸作用域”来处理这种情况。可逃逸作用域允许一个句柄被“提升”,从而“逃逸”当前作用域,其生命周期从当前作用域变为外层作用域。

【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.】