#napi #future #local #async #javascript #async-channel #extend

napi_async_local

扩展 napi-rs 以实现运行本地 futures 的功能

3 个不稳定版本

0.2.0 2024 年 7 月 30 日
0.1.1 2024 年 7 月 11 日
0.1.0 2024 年 7 月 11 日

#565异步

Download history 211/week @ 2024-07-08 5/week @ 2024-07-15 151/week @ 2024-07-29

每月 367 次下载

MIT 许可证

36KB
905

Napi Async Local 扩展

该包扩展 napi-rs 以实现运行本地 futures 的功能。

使用

use napi::*;
use napi_derive::napi;
use napi_async_local::SpawnLocalExt;

#[napi]
fn my_js_func(env: Env) -> napi::Result<JsObject> {
  env.spawn_local(|env| async {
    println!("Running async!");
    Ok(())
  })
}

这允许在不阻塞主 JavaScript 线程的同时使用 Channels、Timers 和其他异步工具,同时保留与底层 JavaScript 值交互的能力。

安装

使用以下命令安装包:

cargo add napi_async_local

使用

使用 env.spawn_local() 在本地线程上启动一个非阻塞的 future。返回一个异步闭包中返回值的 Promise。

为确保 NapiValue 类型在父函数作用域的生命周期内可用,请确保在异步闭包中将将使用的 NapiValue 类型包装在 JsRc 中,并将 GC 代理给 Rust。

定时器 & 回调

use std::time::Duration;

use napi::*;
use napi_derive::napi;
use napi_async_local::JsRc;
use napi_async_local::JsRcExt;
use napi_async_local::SpawnLocalExt;
use async_std::task;

#[napi]
fn my_js_func(env: Env, callback: JsRc<JsFunction>) -> napi::Result<JsObject> {
  env.spawn_local(move |env| async move {
    task::sleep(Duration::from_millis(1000)).await;
    callback.inner(&env)?.call_without_args(None)?;
    Ok(())
  })
}
import napi from './napi.node'

napi.myJsFunc(() => console.log('Waited for 1 second'))

通道和线程

您可以将操作系统线程与异步通道结合使用,以协调非线程工作负载。

我建议使用 async_std 作为异步工具,因为自定义 Futures 反应器与 Tokio 工具不兼容。

use std::thread;
use std::time::Duration;
 
use napi::*;
use napi_derive::napi;
use napi_async_local::JsRc;
use napi_async_local::JsRcExt;
use napi_async_local::SpawnLocalExt;
use async_std::channel;
 
#[napi]
fn my_js_func(env: Env, callback: JsRc<JsFunction>) -> napi::Result<JsObject> {
  let (tx, rx) = channel::unbounded();
 
  thread::spawn(move || {
    for i in 0..10 {
      tx.send_blocking(i).unwrap();
      thread::sleep(Duration::from_millis(1000));
    }
  });
 
  env.spawn_local(move |env| async move {
    while let Ok(value) = rx.recv().await {
      println!("Got number: {}", value);
      callback.inner(&env)?.call(None, &[env.create_int32(value)?])?;
    }
 
    Ok(())
  })
}

开发

要设置开发环境,请确保您已安装 just,然后运行

npm install
just run example-a

依赖关系

~1.5–7MB
~52K SLoC