Rust WebAssembly计时器库zduny-wasm-timer的使用,实现高性能跨平台时间管理与延迟任务
Rust WebAssembly计时器库zduny-wasm-timer的使用,实现高性能跨平台时间管理与延迟任务
zduny-wasm-timer是一个Rust库,它导出了Instant
、Delay
、Interval
和Timeout
结构体。
在非WASM目标上,它会重新导出tokio-timer
中的类型。在WASM目标上,它使用web-sys
和js-sys
来实现这些功能。
该库支持在Web Workers中使用。
安装
在项目目录中运行以下Cargo命令:
cargo add zduny-wasm-timer
或者在Cargo.toml中添加以下行:
zduny-wasm-timer = "0.2.9"
完整示例代码
以下是一个使用zduny-wasm-timer实现计时器和延迟任务的完整示例:
use zduny_wasm_timer::{Delay, Instant, Interval, Timeout};
use std::time::Duration;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn run_timer_examples() {
// 示例1:使用Instant测量时间间隔
let start = Instant::now();
// 执行一些操作...
let elapsed = start.elapsed();
log::info!("操作耗时: {:?}", elapsed);
// 示例2:使用Delay实现延迟任务
Delay::new(Duration::from_secs(2)).await;
log::info!("2秒延迟后执行的任务");
// 示例3:使用Interval实现定时任务
let mut interval = Interval::new(Duration::from_secs(1));
for _ in 0..5 {
interval.next().await;
log::info!("每秒触发一次的定时任务");
}
// 示例4:使用Timeout设置超时
let timeout = Timeout::new(Duration::from_secs(3), async {
log::info!("超时前完成的任务");
});
if let Err(_) = timeout.await {
log::info!("任务超时");
}
}
使用说明
- Instant - 用于测量时间间隔的高精度时间点
- Delay - 用于实现延迟任务的未来(Future)
- Interval - 用于创建周期性定时器的迭代器
- Timeout - 用于设置任务超时
相关技术
- wasm-bindgen
- web-sys
- js-sys
该库采用MIT许可证,适用于需要跨平台时间管理和延迟任务处理的WebAssembly应用场景。
扩展完整示例demo
以下是一个更完整的WASM计时器应用示例,展示了如何在浏览器环境中使用zduny-wasm-timer:
use zduny_wasm_timer::{Delay, Instant, Interval, Timeout};
use std::time::Duration;
use wasm_bindgen::prelude::*;
use web_sys::console;
// 初始化日志
#[wasm_bindgen(start)]
pub fn start() {
console_error_panic_hook::set_once();
console::log_1(&"WASM计时器应用已启动".into());
}
// 计时器功能封装
#[wasm_bindgen]
pub struct TimerApp {
interval: Option<Interval>,
timeout: Option<Timeout>,
}
#[wasm_bindgen]
impl TimerApp {
// 创建新计时器应用
pub fn new() -> Self {
Self {
interval: None,
timeout: None,
}
}
// 测量函数执行时间
pub fn measure(&self, callback: &js_sys::Function) {
let start = Instant::now();
// 调用JS回调函数
let _ = callback.call0(&JsValue::NULL);
let duration = start.elapsed();
console::log_1(&format!("函数执行耗时: {:?}", duration).into());
}
// 启动延迟任务
pub async fn start_delay(&self, seconds: u64) {
Delay::new(Duration::from_secs(seconds)).await;
console::log_1(&format!("{}秒延迟任务完成", seconds).into());
}
// 启动定时器
pub fn start_interval(&mut self, seconds: u64, callback: js_sys::Function) {
let mut interval = Interval::new(Duration::from_secs(seconds));
wasm_bindgen_futures::spawn_local(async move {
loop {
interval.next().await;
let _ = callback.call0(&JsValue::NULL);
}
});
self.interval = Some(interval);
}
// 设置超时任务
pub fn set_timeout(&mut self, seconds: u64, callback: js_sys::Function) {
let timeout = Timeout::new(Duration::from_secs(seconds), async {
let _ = callback.call0(&JsValue::NULL);
});
wasm_bindgen_futures::spawn_local(async move {
if let Err(_) = timeout.await {
console::log_1(&"任务超时".into());
}
});
self.timeout = Some(timeout);
}
}
这个扩展示例展示了:
- 如何封装计时器功能到WASM可调用的结构中
- 如何与JavaScript交互(通过回调函数)
- 更完整的异步任务处理
- 错误处理和日志记录
使用时需要在JavaScript中这样调用:
// 初始化WASM模块
import init, { TimerApp } from './pkg/your_wasm_module.js';
async function run() {
await init();
const timer = TimerApp.new();
// 测量性能
timer.measure(() => {
// 要测量的代码
});
// 延迟任务
timer.start_delay(3);
// 定时器
timer.start_interval(1, () => {
console.log("定时器触发");
});
// 超时任务
timer.set_timeout(5, () => {
console.log("任务完成");
});
}
run();
1 回复
zduny-wasm-timer:Rust WebAssembly计时器库的使用指南
简介
zduny-wasm-timer
是一个专为Rust和WebAssembly设计的计时器库,提供了高性能的跨平台时间管理和延迟任务执行功能。它特别适合需要在WebAssembly环境中处理时间相关操作的场景。
主要特性
- 跨平台支持(包括Web和原生环境)
- 高性能的时间管理
- 延迟任务执行
- 定时器功能
- 与Web API无缝集成
安装
在Cargo.toml中添加依赖:
[dependencies]
zduny-wasm-timer = "0.2"
基本用法
延迟执行
use zduny_wasm_timer::{Delay, Instant};
async fn delayed_task() {
let start = Instant::now();
Delay::new(std::time::Duration::from_secs(1)).await;
println!("执行延迟1秒后的任务,实际延迟时间: {:?}", start.elapsed());
}
定时器
use zduny_wasm_timer::{Interval, Instant};
async fn periodic_task() {
let mut interval = Interval::new(std::time::Duration::from_secs(1));
let start = Instant::now();
for _ in 0..5 {
interval.next().await;
println!("定时任务执行,距离开始时间: {:?}", start.elapsed());
}
}
时间测量
use zduny_wasm_timer::Instant;
fn measure_time() {
let start = Instant::now();
// 执行一些操作...
std::thread::sleep(std::time::Duration::from_millis(500));
let elapsed = start.elapsed();
println!("操作耗时: {:?}", elapsed);
}
在WebAssembly中使用
use wasm_bindgen::prelude::*;
use zduny_wasm_timer::{Delay, Instant};
#[wasm_bindgen]
pub async fn start_timer(seconds: u32) {
let start = Instant::now();
Delay::new(std::time::Duration::from_secs(seconds.into())).await;
let elapsed = start.elapsed();
web_sys::console::log_1(&format!("定时器触发,延迟了 {:?}", elapsed).into());
}
高级用法
取消延迟任务
use zduny_wasm_timer::{Delay, Instant};
async fn cancellable_delay() {
let delay = Delay::new(std::time::Duration::from_secs(5));
// 在另一个任务中取消延迟
let handle = delay.handle();
std::thread::spawn(move || {
std::thread::sleep(std::time::Duration::from_secs(2));
handle.cancel();
});
match delay.await {
Ok(()) => println!("延迟完成"),
Err(_) => println!("延迟被取消"),
}
}
精确时间间隔
use zduny_wasm_timer::{Interval, Instant};
async fn precise_interval() {
let mut interval = Interval::new_at(
Instant::now() + std::time::Duration::from_secs(1),
std::time::Duration::from_secs(1)
);
for _ in 0..5 {
interval.next().await;
println!("精确时间间隔任务执行");
}
}
完整示例Demo
下面是一个完整的WebAssembly应用示例,展示了如何使用zduny-wasm-timer库:
use wasm_bindgen::prelude::*;
use zduny_wasm_timer::{Delay, Instant, Interval};
// 延迟执行示例
#[wasm_bindgen]
pub async fn demo_delay(seconds: u32) {
let start = Instant::now();
Delay::new(std::time::Duration::from_secs(seconds.into())).await;
let elapsed = start.elapsed();
web_sys::console::log_1(&format!("延迟任务完成,延迟了 {:?}", elapsed).into());
}
// 定时器示例
#[wasm_bindgen]
pub async fn demo_interval(count: u32) {
let mut interval = Interval::new(std::time::Duration::from_secs(1));
let start = Instant::now();
for i in 0..count {
interval.next().await;
web_sys::console::log_1(
&format!("定时器触发 #{}, 距离开始: {:?}", i+1, start.elapsed()).into()
);
}
}
// 取消延迟任务示例
#[wasm_bindgen]
pub async fn demo_cancellable() {
let delay = Delay::new(std::time::Duration::from_secs(5));
let handle = delay.handle();
// 在wasm中可以使用setTimeout模拟取消操作
let closure = Closure::once(move || handle.cancel());
web_sys::window()
.unwrap()
.set_timeout_with_callback_and_timeout_and_arguments_0(
closure.as_ref().unchecked_ref(),
2000
)
.unwrap();
match delay.await {
Ok(()) => web_sys::console::log_1(&"延迟完成".into()),
Err(_) => web_sys::console::log_1(&"延迟被取消".into()),
}
}
注意事项
- 在WebAssembly环境中使用时,确保你的项目配置了正确的
target
(如wasm32-unknown-unknown
) - 对于长时间运行的任务,考虑使用
set_timeout
或set_interval
的Web API替代方案 - 在原生环境和WebAssembly环境中,时间精度可能有所不同
性能建议
- 避免创建大量短时间间隔的定时器
- 对于高频时间测量,考虑使用
Instant::now()
而不是系统时间 - 重用
Interval
实例而不是创建新的实例
这个库为Rust和WebAssembly提供了可靠的时间管理解决方案,特别适合需要跨平台时间操作和延迟任务执行的场景。