双向 Rust ↔ TypeScript FFI

基于 napi-rsThreadsafeFunction 实现 Rust 主动回调 TypeScript, 探索两种语言的深度协作。

🔄 双向调用

TS 调用 Rust 函数,Rust 也能通过 ThreadsafeFunction 在任意线程回调 TS,打破单向调用限制。

🧵 线程安全

利用 napi-rs 的线程安全回调机制,Rust 可在独立线程中安全地向 Node.js 主线程发送数据。

⏱️ 异步任务

Rust 端启动耗时计算或 I/O 任务,完成后通过回调将结果推回 TypeScript,不阻塞事件循环。

📋 最佳实践

提供可直接复用的代码示例,演示 napi-rs 在实际项目中的正确用法和模式。

// Rust 侧 (src/lib.rs) use napi::threadsafe_function::*; use napi_derive::napi; #[napi] pub fn run_async_task(callback: ThreadsafeFunction<String, ErrorStrategy::CalleeHandled>) { // 在独立线程中执行任务 std::thread::spawn(move || { // 模拟耗时操作 std::thread::sleep(std::time::Duration::from_secs(2)); // Rust 主动回调 TypeScript callback.call( Ok("Hello from Rust! 👋".to_string()), ThreadsafeFunctionCallMode::NonBlocking, ); }); }
// TypeScript 侧 import { runAsyncTask } from '@tsffi/two-way'; // Rust 函数完成后会回调这个函数 runAsyncTask((message: string) => { console.log('Rust says:', message); // "Hello from Rust! 👋" }); console.log('Task started, not blocked!');

📊 进度上报

Rust 执行长任务时,通过多次回调实时向 TS 报告进度百分比。

📡 事件驱动

Rust 监听系统事件、文件变化等,主动通知 TS 层响应。

🔀 流式处理

Rust 分批产出数据,通过回调逐块推送给 TS,实现流式管道。

⚡ Worker 模式

多个 Rust 线程并行计算,各自回调 TS 汇总结果。

// ThreadsafeFunction 支持的模式: // 1. NonBlocking — 不阻塞 JS 主线程,建议默认使用 // 2. Blocking — 等待 JS 线程空闲后执行 // 错误处理策略: // 1. CalleeHandled — 由 TS 回调函数自行处理错误 // 2. Fatal — 回调错误视为致命,终止进程 // 生命周期管理: // 使用 AbortSignal 或 drop handle 来取消挂起的回调, // 避免 Rust 线程在 JS 退出后继续尝试回调。