⚡ 使用 #[neon::export] 异步
最简单的异步方式:
rust
#[neon::export]
async fn fetch_data(url: String) -> Result {
let response = reqwest::get(&url).await?;
let body = response.text().await?;
Ok(body)
}
JavaScript 端自动获得 Promise:
javascript
const { fetchData } = require('./native');
async function main() {
const data = await fetchData('https://api.example.com/data');
console.log(data);
}
🔄 使用 Task
更灵活的异步任务:
rust
use neon::prelude::*;
struct ComputeTask {
input: i32,
}
impl Task for ComputeTask {
type Output = i32;
type Error = String;
type JsEvent = JsNumber;
fn perform(&self) -> Result {
// 在后台线程执行
Ok(self.input * 2)
}
fn complete(self, mut cx: TaskContext, result: Result) -> JsResult {
match result {
Ok(val) => Ok(cx.number(val as f64)),
Err(e) => cx.throw_error(e),
}
}
}
fn compute_async(mut cx: FunctionContext) -> JsResult {
let input = cx.argument::(0)?.value(&mut cx) as i32;
let task = ComputeTask { input };
let promise = task.schedule(&mut cx)?;
Ok(promise)
}
📋 Promise 创建
rust
use neon::prelude::*;
fn create_promise(mut cx: FunctionContext) -> JsResult {
let (deferred, promise) = cx.promise();
// 可以在其他线程 resolve
let channel = cx.channel();
thread::spawn(move || {
let result = expensive_computation();
channel.send(move |mut cx| {
let value = cx.string(result);
deferred.resolve(&mut cx, value);
Ok(())
});
});
Ok(promise)
}
⚠️ 注意事项
- 异步函数不会阻塞 JavaScript 主线程
- 长时间任务使用 Task 或 #[neon::export] async
- 跨线程通信使用 Channel
- 避免在异步中访问 JavaScript 对象