Skip to content

大多数情况下,NAPI-RS 的各种高层抽象和结构已经封装了 Node-API。但在某些场景中,你仍需要直接访问底层 Node-API。

Env 结构体提供对 Node-API 环境的访问,可用于创建 JavaScript 值、处理错误、管理内存以及与 JavaScript 运行时交互。

创建字符串和 Symbol

create_string

从可转换为 &str 的 Rust 类型创建 JavaScript 字符串。

rust
pub fn create_string<S: AsRef<str>>(&self, s: S) -> Result<JsString<'_>>

示例:

rust
let js_string = env.create_string("Hello, World!")?;

create_string_from_std

从 Rust String 创建 JavaScript 字符串。

rust
pub fn create_string_from_std<'env>(&self, s: String) -> Result<JsString<'env>>

create_string_from_c_char

从 C 风格字符串指针创建 JavaScript 字符串,用于 C FFI 场景。

INFO

如果 C 字符串以 null 结尾,可以把 NAPI_AUTO_LENGTH 作为 len 参数传入。

rust
pub unsafe fn create_string_from_c_char<'env>(
  &self,
  data_ptr: *const c_char,
  len: isize,
) -> Result<JsString<'env>>

create_string_utf16

从 UTF-16 编码数据创建 JavaScript 字符串。

rust
pub fn create_string_utf16<C: AsRef<[u16]>>(&self, chars: C) -> Result<JsString<'_>>

create_string_latin1

从 Latin-1 编码数据创建 JavaScript 字符串。

rust
pub fn create_string_latin1<C: AsRef<[u8]>>(&self, chars: C) -> Result<JsString<'_>>

create_symbol

创建一个可选描述的 JavaScript symbol。

rust
pub fn create_symbol(&self, description: Option<&str>) -> Result<JsSymbol<'_>>

symbol_for

INFO

需要 napi9 feature。

从全局 symbol registry 创建或获取 symbol。

rust
pub fn symbol_for(&self, description: &str) -> Result<JsSymbol<'_>>

错误处理

get_last_error_info

获取最近一次错误的扩展信息。

rust
pub fn get_last_error_info(&self) -> Result<ExtendedErrorInfo>

throw

将任意 JavaScript 值作为异常抛出。

rust
pub fn throw<T: ToNapiValue>(&self, value: T) -> Result<()>

throw_error

使用给定消息和可选错误码抛出 JavaScript Error。

rust
pub fn throw_error(&self, msg: &str, code: Option<&str>) -> Result<()>

throw_range_error

使用给定消息和可选错误码抛出 JavaScript RangeError。

rust
pub fn throw_range_error(&self, msg: &str, code: Option<&str>) -> Result<()>

throw_type_error

使用给定消息和可选错误码抛出 JavaScript TypeError。

rust
pub fn throw_type_error(&self, msg: &str, code: Option<&str>) -> Result<()>

throw_syntax_error 需要 napi9

使用给定消息和可选错误码抛出 JavaScript SyntaxError。

rust
pub fn throw_syntax_error<S: AsRef<str>, C: AsRef<str>>(&self, msg: S, code: Option<C>)

fatal_error

触发致命错误并立即终止进程。

rust
pub fn fatal_error(self, location: &str, message: &str)

fatal_exception

INFO

需要 napi3 feature。

在 JavaScript 中触发 uncaughtException。适用于抛出不可恢复异常的异步回调。

rust
pub fn fatal_exception(&self, err: Error)

create_error

从 Rust Error 创建 JavaScript error 对象。

rust
pub fn create_error(&self, e: Error) -> Result<Object<'_>>

创建函数和类

create_function

从原生回调创建 JavaScript 函数。

rust
pub fn create_function<Args: JsValuesTupleIntoVec, Return>(
  &self,
  name: &str,
  callback: Callback,
) -> Result<Function<'_, Args, Return>>

示例:

INFO

在函数名后添加 _c_callback 后缀,即可访问其 C Callback。以下示例中,custom_function_c_callbackcustom_functionC 回调。

lib.rs
rust
use napi::bindgen_prelude::*;
use napi_derive::napi;

#[napi]
pub fn create_function(env: &Env) -> Result<Function<u32, u32>> {
  env.create_function("customFunction", custom_function_c_callback) 
}

#[napi(no_export)]
fn custom_function(input: u32) -> u32 { 
  input * 2
}

INFO

no_export 属性用于防止函数导出到 JavaScript 侧。

custom_function 未被导出,因此 JavaScript 侧不可见,但它的 C 回调用于在 fn create_function 中创建 Function。用法如下:

index.ts
ts
import { createFunction } from './index.js'

const customFunction = createFunction()
console.log(customFunction(2)) // 4

create_function_from_closure

INFO

需要 napi5 feature。

从 Rust closure 创建 JavaScript 函数。

rust
pub fn create_function_from_closure<Args: JsValuesTupleIntoVec, Return, F>(
  &self,
  name: &str,
  callback: F,
) -> Result<Function<'_, Args, Return>>
where
  Return: ToNapiValue,
  F: 'static + Fn(FunctionCallContext) -> Result<Return>,

示例:

lib.rs
rust
use napi::bindgen_prelude::*;
use napi_derive::napi;

#[napi]
pub fn create_function(env: &Env) -> Result<Function<u32, u32>> {
  let var_moved_into_closure = 42; // this variable is moved into the closure
  env.create_function_from_closure("rustClosure", move |ctx| {
    // get the first argument from the JavaScript side
    let result = var_moved_into_closure + ctx.get::<u32>(0)?; 
    Ok(result)
  })
}

⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️ ⬇️

index.ts
ts
import { createFunction } from './index.js'

const rustClosure = createFunction()
console.log(rustClosure(2)) // 44

define_class

使用给定构造函数和属性创建 JavaScript 类。

rust
pub fn define_class<Args: JsValuesTupleIntoVec>(
  &self,
  name: &str,
  constructor_cb: Callback,
  properties: &[Property],
) -> Result<Function<'_, Args, Unknown<'_>>>

内存管理

adjust_external_memory

告知 V8 JavaScript 对象所持有的外部分配内存量。

rust
pub fn adjust_external_memory(&self, size: i64) -> Result<i64>

run_in_scope

在 handle scope 内执行函数,以便管理临时对象的内存。

rust
pub fn run_in_scope<T, F>(&self, executor: F) -> Result<T>
where
  F: FnOnce() -> Result<T>,

环境清理

add_env_cleanup_hook

INFO

需要 napi3 feature。

注册在环境拆除时调用的清理 hook。

rust
pub fn add_env_cleanup_hook<T, F>(
  &self,
  cleanup_data: T,
  cleanup_fn: F,
) -> Result<CleanupEnvHook<T>>
where
  T: 'static,
  F: 'static + FnOnce(T),

remove_env_cleanup_hook

INFO

需要 napi3 feature。

移除先前注册的清理 hook。

rust
pub fn remove_env_cleanup_hook<T>(&self, hook: CleanupEnvHook<T>) -> Result<()>
where
  T: 'static,

add_async_cleanup_hook

INFO

需要 napi8 feature。

注册异步清理 hook。

rust
pub fn add_async_cleanup_hook<Arg, F>(&self, arg: Arg, cleanup_fn: F) -> Result<()>
where
  F: FnOnce(Arg),
  Arg: 'static,

add_removable_async_cleanup_hook

INFO

需要 napi8 feature。

注册可移除的异步清理 hook。

rust
pub fn add_removable_async_cleanup_hook<Arg, F>(
  &self,
  arg: Arg,
  cleanup_fn: F,
) -> Result<AsyncCleanupHook>
where
  F: FnOnce(Arg),
  Arg: 'static,

执行脚本与环境信息

run_script

执行 JavaScript 字符串并返回结果。

rust
pub fn run_script<S: AsRef<str>, V: FromNapiValue>(&self, script: S) -> Result<V>

示例:

rust
let result: i32 = env.run_script("2 + 2")?;
assert_eq!(result, 4);

get_napi_version

获取 N-API 版本(process.versions.napi)。

rust
pub fn get_napi_version(&self) -> Result<u32>

get_node_version

获取 Node.js 版本信息。

rust
pub fn get_node_version(&self) -> Result<NodeVersion>

get_module_file_name

INFO

需要 napi9 feature。

以 URL 形式获取当前运行的 JS 模块文件路径。

rust
pub fn get_module_file_name(&self) -> Result<String>

get_uv_event_loop

INFO

需要 napi2 feature。

获取底层 libuv event loop 的指针。

rust
pub fn get_uv_event_loop(&self) -> Result<*mut sys::uv_loop_s>

实例数据管理

set_instance_data

INFO

需要 napi6 feature。

将数据与当前运行的 Agent 关联。

rust
pub fn set_instance_data<T, Hint, F>(&self, native: T, hint: Hint, finalize_cb: F) -> Result<()>
where
  T: 'static,
  Hint: 'static,
  F: FnOnce(FinalizeContext<T, Hint>),

get_instance_data

INFO

需要 napi6 feature。

获取先前与当前运行 Agent 关联的数据。

rust
pub fn get_instance_data<T>(&self) -> Result<Option<&'static mut T>>
where
  T: 'static,

异步与 Future 支持

spawn

在线程池中运行任务并返回 AsyncWorkPromise

rust
pub fn spawn<T: 'static + Task>(&self, task: T) -> Result<AsyncWorkPromise<T::JsValue>>

spawn_future

INFO

需要 tokio_rtnapi4 feature。

生成 Rust future 并返回 JavaScript Promise。

rust
pub fn spawn_future<
  T: 'static + Send + ToNapiValue,
  F: 'static + Send + Future<Output = Result<T>>,
>(&self, fut: F) -> Result<PromiseRaw<'_, T>>

spawn_future_with_callback

INFO

需要 tokio_rtnapi4 feature。

生成 future,并使用回调处理结果。

rust
pub fn spawn_future_with_callback<
  T: 'static + Send,
  V: ToNapiValue,
  F: 'static + Send + Future<Output = Result<T>>,
  R: 'static + FnOnce(Env, T) -> Result<V>,
>(&self, fut: F, callback: R) -> Result<PromiseRaw<'_, V>>

创建 Date

create_date

INFO

需要 napi5 feature。

从时间戳创建 JavaScript Date 对象。

rust
pub fn create_date(&self, time: f64) -> Result<JsDate<'_>>

JSON 序列化

to_js_value

INFO

需要 serde-json feature。

使用 serde 将 Rust 结构体序列化为 JavaScript 值。

rust
pub fn to_js_value<'env, T>(&self, node: &T) -> Result<Unknown<'env>>
where
  T: Serialize,

from_js_value

INFO

需要 serde-json feature。

使用 serde 将 JavaScript 值反序列化为 Rust 类型。

rust
pub fn from_js_value<'v, T, V>(&self, value: V) -> Result<T>
where
  T: DeserializeOwned,
  V: JsValue<'v>,

值比较

strict_equals

对两个 JavaScript 值执行严格相等比较(等同于 ===)。

rust
pub fn strict_equals<'env, A: JsValue<'env>, B: JsValue<'env>>(
  &self,
  a: A,
  b: B,
) -> Result<bool>