基于 call/cc 的现代异步编程库 - 为 Chez Scheme 打造
完整的 async/await、Promise、协程调度器和 libuv 集成
;; async/await 语法 (async (let ([result (await (async-sleep loop 1000))]) (printf "Waited 1 second~n") result)) ;; 组合器 (async-all (list promise1 promise2 promise3)) (async-race (list fast-promise slow-promise)) (async-timeout promise 5000) ;; 取消令牌 (define cts (make-cancellation-token-source)) (define task (long-running-operation (cts 'token))) (cts 'cancel!) ; 取消操作- ✅ 缓冲区工具整合(减少 16 行样板代码)
- ✅ 错误回调标准化(4 个文件更新)
- ✅ 读写模式提取(2 个文件简化)
- ✅ 全部 39 个测试通过
详见:项目状态
1. 真正的 async/await 语法
;; 像 JavaScript/C# 一样简洁 (async (let ([data (await (tcp-read-async client))]) (await (tcp-write-async client data))))2. 基于 call/cc 的协程
- 无需状态机
- 无需 CPS 变换
- 保持代码自然结构
3. 工业级事件循环
- 基于 libuv(Node.js 同款)
- 零 C/C++ 包装层
- 直接 FFI 绑定
4. 完整的并发控制
;; 等待所有任务 (async-all promises) ;; 竞速 (async-race promises) ;; 超时控制 (async-timeout promise 5000) ;; 取消机制 (cancellable-operation token)| 特性 | chez-async | Racket 异步 | 传统回调 |
|---|---|---|---|
| async/await | ✅ 原生支持 | ❌ 无 | ❌ 无 |
| 协程 | ✅ call/cc | ✅ delimited continuations | ❌ 无 |
| 取消 | ✅ CancellationToken | ✅ custodian | ❌ 手动 |
| 组合器 | ✅ 完整 | ✅ 完整 | |
| libuv 集成 | ✅ 直接 FFI | ❌ 无 | ✅ 可能有 |
| 学习曲线 | 低 | 中 | 高 |
(define (fetch-user-data user-id) (async (let* ([user (await (db-query "SELECT * FROM users WHERE id = ?" user-id))] [posts (await (db-query "SELECT * FROM posts WHERE user_id = ?" user-id))]) (list user posts))))(promise-then my-promise (lambda (value) (printf "Success: ~a~n" value)) (lambda (error) (printf "Error: ~a~n" error)))async-all- 并行等待所有任务async-race- 返回最快完成的任务async-any- 返回首个成功的任务async-timeout- 为任务添加超时async-delay- 延迟执行async-catch- 捕获错误async-finally- 清理资源
(define cts (make-cancellation-token-source)) (define task (async (when (token-cancelled? (cts 'token)) (raise (make-operation-cancelled-error))) (await (long-operation)))) ;; 在其他地方取消 (cts 'cancel!)- TCP/UDP 套接字
- 文件系统(异步)
- DNS 解析
- 进程管理
- 信号处理
- 定时器
- Pipe/TTY
当前版本: Phase 4 完成 (2026-02-05) 状态: 生产就绪 ✅
- ✅ 基于 call/cc 的协程实现
- ✅ 协程调度器和事件循环集成
- ✅ Suspend/Resume 机制
- ✅
async宏(创建异步函数) - ✅
await宏(等待 Promise) - ✅ Promise/A+ 实现
- ✅ 错误传播和异常处理
- ✅ TCP 套接字(客户端/服务器)
- ✅ UDP 套接字
- ✅ 文件系统(fs)
- ✅ DNS 解析
- ✅ Pipe 和 TTY
- ✅ 信号处理
- ✅ 进程管理
- ✅ 文件监控
- ✅ async/await 组合器(8个)
- ✅ 取消令牌(CancellationToken)
- ✅ 完整测试覆盖(39/39 通过)
- ✅ 代码质量优化重构
✅ TCP: 8/8 通过 ✅ UDP: 8/8 通过 ✅ Pipe: 7/7 通过 ✅ Promise: 13/13 通过 ✅ Stream: 3/3 通过 ─────────────────────── 总计: 39/39 测试通过 ✅ - Chez Scheme 10.0+
- libuv 1.x
# Debian/Ubuntu sudo apt-get install chezscheme libuv1-dev # macOS brew install chezscheme libuv # FreeBSD sudo pkg install chez-scheme libuv#!/usr/bin/env scheme-script (import (chez-async)) ;; 创建异步函数 (define (hello-async) (async (printf "Starting...~n") (await (async-sleep (uv-default-loop) 1000)) (printf "Hello, async world!~n"))) ;; 运行 (define loop (uv-default-loop)) (define p (hello-async)) (uv-run loop 'default)(import (chez-async)) (define (fetch-data url) (async (printf "Fetching ~a...~n" url) (await (async-sleep (uv-default-loop) 1000)) (string-append "Data from " url))) (define loop (uv-default-loop)) (define p (fetch-data "http://example.com")) (promise-then p (lambda (data) (printf "Got: ~a~n" data) (uv-stop loop))) (uv-run loop 'default)(define (parallel-fetch) (async (let ([urls '("url1" "url2" "url3")]) (let ([promises (map fetch-data urls)]) ;; 等待所有任务完成 (await (async-all promises))))))(import (chez-async)) (define (handle-client client) (async (let loop () (let ([data (await (tcp-read-async client))]) (when (bytevector? data) (await (tcp-write-async client data)) (loop)))))) (define (start-server) (let* ([loop (uv-default-loop)] [server (uv-tcp-init loop)]) (uv-tcp-bind server "0.0.0.0" 8080) (uv-tcp-listen server 128 (lambda (srv err) (unless err (let ([client (uv-tcp-accept srv)]) (handle-client client))))) (uv-run loop 'default)))(define (with-timeout) (async (guard (e [(timeout-error? e) (printf "Operation timed out!~n")]) (await (async-timeout (long-running-operation) 5000))))) (define (cancellable-task) (let ([cts (make-cancellation-token-source)]) ;; 5秒后自动取消 (async-sleep loop 5000) (cts 'cancel!) ;; 运行可取消任务 (async (let ([token (cts 'token)]) (await (long-operation-with-cancellation token))))))(async body ...) ; 创建异步函数,返回 Promise (await promise) ; 等待 Promise 完成(make-promise loop executor) ; 创建 Promise (promise-then p on-fulfilled [on-rejected]) ; 链式调用 (promise-catch p on-rejected) ; 捕获错误 (promise-finally p on-finally) ; 清理资源 (promise-resolved loop value) ; 创建已完成的 Promise (promise-rejected loop reason) ; 创建已拒绝的 Promise(async-all promises) ; 等待全部完成 (async-race promises) ; 返回最快的 (async-any promises) ; 返回首个成功 (async-timeout promise ms) ; 添加超时 (async-sleep loop ms) ; 延迟 (async-delay loop ms thunk) ; 延迟执行 (async-catch thunk) ; 错误处理 (async-finally promise cleanup) ; 资源清理(make-cancellation-token-source) ; 创建取消源 (cts 'token) ; 获取令牌 (cts 'cancel!) ; 请求取消 (token-cancelled? token) ; 检查是否已取消 (token-register! token callback) ; 注册取消回调;; TCP (uv-tcp-init loop) (uv-tcp-bind tcp addr port) (uv-tcp-listen tcp backlog callback) (uv-tcp-connect tcp addr port callback) ;; UDP (uv-udp-init loop) (uv-udp-bind udp addr port) (uv-udp-send! udp data addr port callback) (uv-udp-recv-start! udp callback) ;; Stream (uv-read-start! stream callback) (uv-write! stream data callback)(uv-fs-open path flags mode callback) (uv-fs-read fd buffer offset callback) (uv-fs-write fd buffer offset callback) (uv-fs-close fd callback) (uv-fs-stat path callback) (uv-fs-unlink path callback)完整 API 文档见:docs/
┌─────────────────────────────────────┐ │ High-Level API (async/await) │ ← 用户代码 │ - async macro │ │ - await macro │ │ - Promise/A+ │ │ - Combinators │ │ - CancellationToken │ └─────────────────────────────────────┘ ↓ ┌─────────────────────────────────────┐ │ Internal (调度器) │ │ - Coroutine Scheduler │ │ - call/cc integration │ │ - Event Loop per-loop storage │ │ - Callback Registry │ └─────────────────────────────────────┘ ↓ ┌─────────────────────────────────────┐ │ Low-Level API (libuv 绑定) │ │ - uv-tcp-*, uv-udp-* │ │ - uv-fs-* │ │ - uv-handle-*, uv-request-* │ └─────────────────────────────────────┘ ↓ ┌─────────────────────────────────────┐ │ FFI Layer (直接 C 绑定) │ │ - %ffi-uv-* functions │ │ - ftype definitions │ └─────────────────────────────────────┘ ↓ [ libuv C Library ] 用户代码: (await promise) ↓ 协程挂起 (call/cc 保存 continuation) ↓ 注册回调到 Promise ↓ 返回事件循环 ↓ ... 事件发生 ... ↓ Promise 完成,回调触发 ↓ 协程恢复 (continuation 调用) ↓ 用户代码继续执行 chez-async/ ├── high-level/ # 用户 API │ ├── promise.ss # Promise 实现 │ ├── async-await.ss # async/await 宏 │ ├── async-combinators.ss # 组合器 │ ├── async-work.ss # 异步任务(线程池) │ ├── cancellation.ss # 取消令牌 │ ├── event-loop.ss # 事件循环封装 │ └── stream.ss # 高级 Stream API │ ├── internal/ # 内部实现 │ ├── scheduler.ss # 协程调度器 │ ├── coroutine.ss # 协程数据结构 │ ├── promise-core.ss # Promise 核心类型 │ ├── loop-registry.ss # 事件循环注册表 │ ├── callback-registry.ss # 回调注册 │ ├── macros.ss # 宏工具 │ ├── handle-utils.ss # 句柄工具宏 │ ├── buffer-utils.ss # 缓冲区工具 │ ├── foreign-utils.ss # FFI 工具函数 │ └── utils.ss # 通用工具 │ ├── low-level/ # libuv 封装 │ ├── tcp.ss # TCP 套接字 │ ├── udp.ss # UDP 套接字 │ ├── stream.ss # Stream 操作 │ ├── pipe.ss # 管道 │ ├── tty.ss # 终端 │ ├── timer.ss # 定时器 │ ├── fs.ss # 文件系统 │ ├── dns.ss # DNS 解析 │ ├── signal.ss # 信号处理 │ ├── process.ss # 进程管理 │ ├── poll.ss # 轮询 │ ├── threadpool.ss # 线程池 │ ├── handle-base.ss # 句柄基础 │ ├── request-base.ss # 请求基础 │ └── sockaddr.ss # 地址处理 │ ├── ffi/ # FFI 绑定 │ ├── types.ss # C 类型定义 │ ├── core.ss # 核心函数 │ ├── handles.ss # 句柄 FFI │ ├── callbacks.ss # 回调 FFI │ ├── tcp.ss # TCP FFI │ ├── udp.ss # UDP FFI │ ├── stream.ss # Stream FFI │ ├── pipe.ss # Pipe FFI │ ├── tty.ss # TTY FFI │ ├── timer.ss # Timer FFI │ ├── fs.ss # FS FFI │ ├── dns.ss # DNS FFI │ ├── signal.ss # Signal FFI │ ├── process.ss # Process FFI │ └── poll.ss # Poll FFI │ ├── tests/ # 测试套件 │ ├── test-tcp.ss # TCP 测试 │ ├── test-udp.ss # UDP 测试 │ ├── test-pipe.ss # Pipe 测试 │ ├── test-promise.ss # Promise 测试 │ ├── test-stream-high.ss # Stream 测试 │ ├── test-coroutine.ss # 协程测试 │ ├── test-cancellation.ss # 取消机制测试 │ └── ... # 更多测试文件 │ ├── examples/ # 示例代码 │ ├── tcp-echo-server.ss # TCP Echo 服务器 │ ├── tcp-echo-client.ss # TCP Echo 客户端 │ ├── udp-echo-server.ss # UDP Echo 服务器 │ ├── async-work-demo.ss # 异步任务示例 │ ├── promise-demo.ss # Promise 示例 │ ├── timer-demo.ss # 定时器示例 │ ├── dns-lookup.ss # DNS 查询示例 │ ├── fs-demo.ss # 文件系统示例 │ ├── pipe-ipc.ss # 管道 IPC 示例 │ └── signal-handler.ss # 信号处理示例 │ └── docs/ # 文档 ├── README.md # 文档索引 ├── async-await-guide.md # async/await 指南 ├── async-combinators-guide.md # 组合器指南 ├── cancellation-guide.md # 取消机制指南 ├── tcp-with-async-await.md # TCP 编程指南 ├── scheduler-architecture.md # 调度器架构 ├── async-implementation-explained.md # async 实现详解 ├── promise-implementation-explained.md # Promise 实现详解 ├── guide/ │ ├── getting-started.md # 快速入门 │ └── async-work.md # 异步任务指南 └── api/ ├── README.md # API 索引 ├── tcp.md # TCP API └── timer.md # Timer API - call/cc 协程实现
- 调度器和事件循环集成
- Suspend/Resume 机制
- async/await 宏
- Promise/A+ 实现
- 错误处理
- TCP/UDP/Pipe/TTY
- 文件系统
- DNS/信号/进程
- 8个组合器函数
- 取消令牌机制
- 代码质量优化
- Stream/Iterator 支持
- 更多性能优化
- 生态系统集成(数据库、HTTP等)
- 快速入门 - 安装和第一个程序
- async/await 指南 - async/await 完整使用指南
- 组合器指南 - 并发控制组合器
- 取消机制指南 - 取消令牌使用
- TCP 编程指南 - 使用 async/await 进行 TCP 编程
- 异步任务指南 - 线程池和后台任务
- async 宏实现详解 - async/await 底层原理
- Promise 实现详解 - Promise 状态机和回调机制
- 调度器架构 - Loop、Scheduler 和 Pending 队列关联
完整文档索引:docs/README.md
项目状态:PROJECT-STATUS.md
cd chez-async # 运行单个测试 scheme --libdirs .:.:. --program tests/test-tcp.ss scheme --libdirs .:.:. --program tests/test-async.ss # 运行所有测试 ./run-tests.sh- libuv 文档 - libuv 官方文档
- Promise/A+ - Promise 规范
- async/await 模式 - 异步编程模式
- call/cc - Continuation 机制
MIT License
欢迎贡献!请查看贡献指南并提交 Pull Request。
- libuv - 提供高性能异步 I/O
- chez-socket - FFI 绑定设计参考
- Chez Scheme 社区 - 提供优秀的 Scheme 实现
Star ⭐ 本项目 如果它对你有帮助!