讨论广场 问答详情
引擎实例是一个独立运行环境,JS对象创建访问等操作必须在同一个引擎实例中进行。在 HarmonyOS 中,如何理解这个概念?
aurora6688 2026-08-23 01:11:12
46 评论 分享
harmonyos

每个napi_value属于特定的HandleScope,HandleScope通过napi_open_handle_scope和napi_close_handle_scope来建立和关闭,HandleScope关闭后,所属的napi_value就会自动释放。有没有相关代码可以实现这个功能呢?

46 评论 分享
写回答
全部评论(1)

生命周期管理

【规则】 合理使用napi_open_handle_scope和napi_close_handle_scope管理napi_value的生命周期,做到生命周期最小化,避免发生内存泄漏问题。

每个napi_value属于特定的HandleScope,HandleScope通过napi_open_handle_scope和napi_close_handle_scope来建立和关闭,HandleScope关闭后,所属的napi_value就会自动释放。

正确示例

// 在for循环中频繁调用napi接口创建js对象时,要加handle_scope及时释放不再使用的资源。
// 下面例子中,每次循环结束局部变量res的生命周期已结束,因此加scope及时释放其持有的js对象,防止内存泄漏
for (int i = 0; i < 100000; i++) {
    napi_handle_scope scope = nullptr;
    napi_open_handle_scope(env, &scope);
    if (scope == nullptr) {
        return;
    }
    napi_value res;
    napi_create_object(env, &res);
    napi_close_handle_scope(env, scope);
}

上下文敏感

【规则】 多引擎实例场景下,禁止通过Node-API跨引擎实例访问JS对象。

引擎实例是一个独立运行环境,JS对象创建访问等操作必须在同一个引擎实例中进行。若在不同引擎实例中操作同一个对象,可能会引发程序崩溃。引擎实例在接口中体现为napi_env。

错误示例

// 线程1执行,在env1创建string对象,值为"bar"
napi_create_string_utf8(env1, "bar", NAPI_AUTO_LENGTH, &string);
// 线程2执行,在env2创建object对象,并将上述的string对象设置到object对象中
napi_status status = napi_create_object(env2, &object);
if (status != napi_ok) {
    napi_throw_error(env, ...);
    return;
}

status = napi_set_named_property(env2, object, "foo", string);
if (status != napi_ok) {
    napi_throw_error(env, ...);
    return;
}

所有的JS对象都隶属于具体的某一napi_env,不可将env1的对象,设置到env2中的对象中。在env2中一旦访问到env1的对象,程序可能会发生崩溃。

异常处理

【建议】 Node-API接口调用发生异常需要及时处理,不能遗漏异常到后续逻辑,否则程序可能发生不可预期行为。

正确示例

// 1.创建对象
napi_status status = napi_create_object(env, &object);
if (status != napi_ok) {
    napi_throw_error(env, ...);
    return;
}
// 2.创建属性值
status = napi_create_string_utf8(env, "bar", NAPI_AUTO_LENGTH, &string);
if (status != napi_ok) {
    napi_throw_error(env, ...);
    return;
}
// 3.将步骤2的结果设置为对象object属性foo的值
status = napi_set_named_property(env, object, "foo", string);
if (status != napi_ok) {
    napi_throw_error(env, ...);
    return;
}

如上示例中,步骤1或者步骤2出现异常时,步骤3都不会正常进行。只有当方法的返回值是napi_ok时,才能保持继续正常运行;否则后续流程可能会出现不可预期的行为。

2026-08-23 01:12:16