← 返回·
探索 JS 异步编程:从 setTimeout 到生成器的六种定时实现
深入探索 JavaScript 异步编程的完整演进路径。以“每秒打印数字”为实例,深入剖析 6 种定时任务实现方法:从经典的闭包问题、Promise 链式调用,到现代的 async/await、生成器函数和函数式编程。

本文将摒弃 Web API (
requestAnimationFrame),在 Node 环境中探讨六种实现方案,展示不同编程范式下的异步控制技巧。
“每秒打印一个数字”这个看似简单的任务,是检验 JavaScript 开发者异步理解程度的绝佳试金石。它不仅考察定时器使用,更串联起闭包、Promise、生成器等核心概念。下面我们由浅入深探索六种实现方案。
1. 经典的 setTimeout 与闭包陷阱
核心思路:
一次循环启动多个定时器,通过延迟时间差实现顺序打印。
关键点:
let创建块级作用域,每个回调捕获独立的i- 若使用
var会共享变量,导致打印十个11 - 闭包陷阱是 JS 异步编程的经典问题
2. setInterval 状态管理
核心思路:
创建周期性执行的"节拍器",外部维护状态。
关键点:
- 需要显式管理状态变量
i - 必须调用
clearInterval避免内存泄漏 - 在组件化开发中,需在卸载生命周期清理定时器
3. 递归 setTimeout 的精准控制
核心思路:
当前任务完成后,再安排下一个任务。
优势:
- 比
setInterval更健壮,避免任务堆积 - 确保执行间隔至少为 1 秒
- 递归终止条件必不可少
4. async/await 同步化表达
核心思路:
用 await 暂停循环执行,模拟同步代码。
优势:
- 代码结构清晰,避免回调地狱
await只暂停当前函数,不阻塞主线程- 现代 JS 异步编程首选方案
5. 生成器函数的精细控制
核心思路:
生成器产出 Promise,外部消费执行。
关键点:
- 执行控制权交给调用方
- 展示迭代器与异步操作结合
- 理解异步迭代器的基础
6. Array.reduce 构建 Promise 链
核心思路:
使用 reduce 动态构建 Promise 执行链。
特点:
- 函数式编程思想的典型应用
- 代码高度声明式但可读性较低
- 展示 Promise 链式执行机制
方案对比总结
异步编程演进启示
从 setTimeout 到 async/await,JavaScript 异步编程经历了显著进化:
- 从回调地狱到同步风格:
async/await让异步代码拥有同步代码的可读性 - 控制粒度精细化:生成器提供更细粒度的执行控制
- 编程范式多元化:函数式与异步的结合拓展了解决方案空间
每种方案都有其适用场景,理解底层机制比死记语法更重要。建议初学者从 async/await 入手,再逐步探索其他模式的精妙之处。