set_timer

Crates.ioset_timer
lib.rsset_timer
version0.1.4
created_at2025-12-02 03:15:27.639225+00
updated_at2025-12-05 08:13:07.363481+00
descriptionRobust interval execution for Rust, supporting async and sync closures. / Rust 健壮的定时间隔执行库,支持异步和同步闭包。
homepagehttps://github.com/js0-site/rust/tree/main/set_timer
repositoryhttps://github.com/js0-site/rust.git
max_upload_size
id1961085
size45,891
i18n.site (i18nsite)

documentation

README

English | 中文


set_timer : Robust Interval Execution for Rust

A robust interval execution library for Rust, supporting both async and sync closures with Tokio integration.

Features

  • Dual Mode Support: Seamlessly handles both synchronous and asynchronous closures.
  • Tokio Integration: Built on top of the powerful tokio runtime for efficient task scheduling.
  • Easy Cancellation: Returns a JoinHandle allowing for immediate and clean task abortion.
  • Familiar API: Designed to mirror the simplicity of JavaScript's setInterval while leveraging Rust's safety and performance.

Usage

Add this to your Cargo.toml:

[dependencies]
set_timer = "0.1.0"

Synchronous Interval

For simple, blocking operations or quick computations:

use std::time::Duration;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
use set_timer::set_timer;

#[tokio::main]
async fn main() {
    let count = Arc::new(AtomicUsize::new(0));
    let count_clone = count.clone();

    // Execute every 100ms
    let handle = set_timer(
        move || {
            count_clone.fetch_add(1, Ordering::SeqCst);
            println!("Tick");
        },
        Duration::from_millis(100),
    );

    // Let it run for a while
    tokio::time::sleep(Duration::from_millis(350)).await;

    // Stop the interval
    handle.abort();
}

Asynchronous Interval

For operations involving I/O, network requests, or other async tasks:

use std::time::Duration;
use set_timer::set_timer_async;

#[tokio::main]
async fn main() {
    let handle = set_timer_async(
        || async {
            // Perform async work here
            println!("Async Tick");
        },
        Duration::from_millis(100),
    );

    tokio::time::sleep(Duration::from_millis(350)).await;
    handle.abort();
}

Design

The library leverages Tokio's lightweight task spawning system.

  1. Task Spawning: When set_timer or set_timer_async is called, a new Tokio task is spawned using tokio::spawn.
  2. Loop Execution: Inside the task, an infinite loop is established.
  3. Execution & Wait:
    • The provided closure is executed (awaited if async).
    • The loop then pauses execution using tokio::time::sleep for the specified period.
  4. Resource Management: The returned JoinHandle serves as a control mechanism. Dropping the handle doesn't stop the task, but calling .abort() on it terminates the loop immediately, ensuring resources are freed.

Tech Stack

  • Language: Rust (Edition 2024)
  • Runtime: Tokio (Async runtime, Time utilities)
  • Testing: Tokio Test, Aok

Directory Structure

.
├── Cargo.toml          # Project configuration and dependencies
├── src/
│   └── lib.rs          # Core library logic (set_timer, set_timer_async)
└── tests/
    └── main.rs         # Integration tests and usage examples

API Reference

set_timer

pub fn set_timer<F>(func: F, period: Duration) -> JoinHandle<()>
where
    F: Fn() + Send + Sync + 'static

Executes a synchronous closure func repeatedly with a fixed time delay period between each call.

set_timer_async

pub fn set_timer_async<F, Fut>(func: F, period: Duration) -> JoinHandle<()>
where
    F: Fn() -> Fut + Send + Sync + 'static,
    Fut: Future<Output = ()> + Send

Executes an asynchronous closure func repeatedly. The period delay occurs after the future returned by func completes.

History

The concept of setInterval originates from the early days of web development. While often associated with JavaScript, it is not actually part of the core ECMAScript specification. Instead, it was introduced as part of the "host environment" API provided by web browsers (the Window interface) and later adopted by Node.js.

It became a cornerstone of dynamic web pages, enabling everything from simple digital clocks to complex polling mechanisms and animations. This crate aims to bring that same essential utility to the Rust ecosystem, adapted for the modern era of asynchronous systems programming.


About

This project is an open-source component of js0.site ⋅ Refactoring the Internet Plan.

We are redefining the development paradigm of the Internet in a componentized way. Welcome to follow us:


set_timer : Rust 健壮的定时间隔执行库

Rust 健壮的定时间隔执行库,支持基于 Tokio 的异步和同步闭包。

功能特性

  • 双模式支持:无缝支持同步和异步闭包的执行。
  • Tokio 集成:基于强大的 tokio 运行时构建,确保高效的任务调度。
  • 轻松取消:返回 JoinHandle,允许立即且干净地中止任务。
  • 熟悉接口:API 设计致敬 JavaScript 的 setInterval,同时兼具 Rust 的安全性和高性能。

使用演示

Cargo.toml 中添加依赖:

[dependencies]
set_timer = "0.1.0"

同步间隔执行

适用于简单的阻塞操作或快速计算:

use std::time::Duration;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
use set_timer::set_timer;

#[tokio::main]
async fn main() {
    let count = Arc::new(AtomicUsize::new(0));
    let count_clone = count.clone();

    // 每 100ms 执行一次
    let handle = set_timer(
        move || {
            count_clone.fetch_add(1, Ordering::SeqCst);
            println!("Tick");
        },
        Duration::from_millis(100),
    );

    // 运行一段时间
    tokio::time::sleep(Duration::from_millis(350)).await;

    // 停止执行
    handle.abort();
}

异步间隔执行

适用于涉及 I/O、网络请求或其他异步任务的操作:

use std::time::Duration;
use set_timer::set_timer_async;

#[tokio::main]
async fn main() {
    let handle = set_timer_async(
        || async {
            // 在此执行异步工作
            println!("Async Tick");
        },
        Duration::from_millis(100),
    );

    tokio::time::sleep(Duration::from_millis(350)).await;
    handle.abort();
}

设计思路

本库利用了 Tokio 轻量级的任务生成系统。

  1. 任务生成:调用 set_timerset_timer_async 时,会使用 tokio::spawn 生成一个新的 Tokio 任务。
  2. 循环执行:在任务内部,建立一个无限 loop 循环。
  3. 执行与等待
    • 执行提供的闭包(如果是异步则进行 await)。
    • 循环随后使用 tokio::time::sleep 暂停执行指定的 period 时长。
  4. 资源管理:返回的 JoinHandle 作为控制机制。丢弃句柄不会停止任务,但在其上调用 .abort() 会立即终止循环,确保资源被释放。

技术堆栈

  • 语言:Rust (Edition 2024)
  • 运行时:Tokio (异步运行时, 时间工具)
  • 测试:Tokio Test, Aok

目录结构

.
├── Cargo.toml          # 项目配置及依赖
├── src/
│   └── lib.rs          # 核心库逻辑 (set_timer, set_timer_async)
└── tests/
    └── main.rs         # 集成测试及使用示例

API 参考

set_timer

pub fn set_timer<F>(func: F, period: Duration) -> JoinHandle<()>
where
    F: Fn() + Send + Sync + 'static

以固定的时间间隔 period 重复执行同步闭包 func

set_timer_async

pub fn set_timer_async<F, Fut>(func: F, period: Duration) -> JoinHandle<()>
where
    F: Fn() -> Fut + Send + Sync + 'static,
    Fut: Future<Output = ()> + Send

重复执行异步闭包 funcperiod 延迟会在 func 返回的 Future 完成后开始计算。

历史背景

setInterval 的概念源于 Web 开发的早期阶段。虽然通常与 JavaScript 联系在一起,但它实际上并不是 ECMAScript 核心规范的一部分。相反,它是作为 Web 浏览器(Window 接口)提供的“宿主环境”API 引入的,后来被 Node.js 采纳。

它成为了动态网页的基石,实现了从简单的数字时钟到复杂的轮询机制和动画等各种功能。本 crate 旨在将这一重要的实用工具带入 Rust 生态系统,并针对现代异步系统编程进行了适配。


关于

本项目为 js0.site ⋅ 重构互联网计划 的开源组件。

我们正在以组件化的方式重新定义互联网的开发范式,欢迎关注:

Commit count: 1

cargo fmt