讲师中心 微信公众号
AI工具推荐 视频效率加速

JavaScript 中 setTimeout 的计时器何时开始倒计时?

夜敏小哥_4951

夜敏小哥_4951

发布时间:2026-09-02 19:21:51

|

837人浏览过

|

来源于php中文网

原创

JavaScript 中 setTimeout 的计时器何时开始倒计时?

setTimeout 的计时器在调用时立即启动,与后续同步代码是否执行完毕无关;其回调执行时机取决于「计时完成时间」与「主线程空闲时刻」的交集,而非注册顺序或延迟数值大小。

`settimeout` 的计时器在调用时立即启动,与后续同步代码是否执行完毕无关;其回调执行时机取决于「计时完成时间」与「主线程空闲时刻」的交集,而非注册顺序或延迟数值大小。

setTimeout 是 JavaScript 事件循环中典型的宏任务(macrotask),它的行为常被误解。关键点在于:计时器的启动是即时的,但回调的执行必须等待当前调用栈清空、且该定时器已到期

在你提供的原始代码中:

setTimeout(() => console.log('first'), 2000);
for (let i = 0; i < 5000; i++) {
  console.log("printing...");
}
setTimeout(() => console.log('second'), 1000);

表面上看,first 的延迟更长(2000ms),second 更短(1000ms),似乎 second 应该后注册却先触发——但实际输出却是 second 先于 first 打印。这并非因为计时器“延迟启动”,而是因为:

两个 setTimeout 都在各自语句执行时立刻启动计时器
first 的计时器在第 1 行就已开始倒计时(目标:2000ms 后触发)
second 的计时器在第 4 行(for 循环结束后)才被调用,此时才开始倒计时(目标:1000ms 后触发)

因此,first 实际等待约 2000ms,而 second 实际等待约 1000ms —— 但它的「起始时刻晚了近 20 秒」(注意:这是常见误区!见下文分析)。

立即学习Java免费学习笔记(深入)”;

⚠️ 重要澄清:那个 for 循环本身几乎瞬间完成(通常 "printing..." 日志——这是 I/O 开销,不属于 JavaScript 主线程阻塞。所以 secondsetTimeout 实际在 first 调用后几毫秒内就被注册,其计时器随即启动。于是:

  • first 计时器:t=0ms 启动 → 预计 t=2000ms 触发
  • second 计时器:t≈5ms 启动 → 预计 t=1005ms 触发

显然,second 会先到期,且主线程在 for 循环结束后即空闲,因此它先执行。

Alibabacloud Sdk Client Initialization For Java
Alibabacloud Sdk Client Initialization For Java

在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。

下载

? 验证方式:用 Date.now() 精确测量同步代码耗时:

console.log('Start');
const start = Date.now();

setTimeout(() => console.log('first'), 2000);

for (let i = 0; i < 5000; i++) {
  console.log("printing..."); // 此处仅增加日志输出,不阻塞 JS 执行
}

console.log(`Loop completed in ${Date.now() - start}ms`); // 通常显示 < 5ms

setTimeout(() => console.log('second'), 1000);

你会发现 Loop completed in Xms 中的 X 极小(远小于 1000),证明 second 的定时器几乎紧随 first 启动。

? 若想模拟真正的「长时间同步阻塞」(如 CPU 密集型任务),应使用忙等待(busy-wait):

setTimeout(() => console.log('first'), 2000);
console.log('Starting blocking task...');
const start = Date.now();
while (Date.now() - start < 3000) {} // 阻塞主线程 3 秒
console.log('Blocking done.');
setTimeout(() => console.log('second'), 1000);

此时输出为:

Start
Blocking done.
second
first

原因:second 在 t≈3000ms 时注册,1000ms 后(t≈4000ms)触发;first 在 t=0ms 注册,2000ms 后(t=2000ms)已到期,但因主线程被占用,只能等到 t≈3000ms 后才入队并执行——所以 second 反而先打印。

✅ 总结:

  • setTimeout 计时器在函数调用时立即启动,不受后续代码影响;
  • 回调能否执行,取决于两个条件同时满足:① 计时器已到期;② 主线程空闲(调用栈为空);
  • 控制台日志输出慢 ≠ JavaScript 执行慢;真实阻塞需避免 I/O,改用计算密集型同步逻辑;
  • 调试时务必用 Date.now()performance.now() 测量实际耗时,而非主观感受。

掌握这一机制,是理解 JavaScript 异步模型与事件循环的关键基础。

热门AI工具

更多
Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

LibLibAI
LibLibAI Hot

一款AI视频创作工具,主要用于国内领先的AI创意平台,以海量模型、低门槛操作与“创作-分享-商业化”生态,让小白与专业创作者都能高效实现图文乃至视频创意表达,适合需要提升相关任务效率的用户。

相关专题

更多
js获取数组长度的方法
js获取数组长度的方法

在js中,可以利用array对象的length属性来获取数组长度,该属性可设置或返回数组中元素的数目,只需要使用“array.length”语句即可返回表示数组对象的元素个数的数值,也就是长度值。php中文网还提供JavaScript数组的相关下载、相关课程等内容,供大家免费下载使用。

4146

2023.06.20

js刷新当前页面
js刷新当前页面

js刷新当前页面的方法:1、reload方法,该方法强迫浏览器刷新当前页面,语法为“location.reload([bForceGet]) ”;2、replace方法,该方法通过指定URL替换当前缓存在历史里(客户端)的项目,因此当使用replace方法之后,不能通过“前进”和“后退”来访问已经被替换的URL,语法为“location.replace(URL) ”。php中文网为大家带来了js刷新当前页面的相关知识、以及相关文章等内容

1049

2023.07.04

js四舍五入
js四舍五入

js四舍五入的方法:1、tofixed方法,可把 Number 四舍五入为指定小数位数的数字;2、round() 方法,可把一个数字舍入为最接近的整数。php中文网为大家带来了js四舍五入的相关知识、以及相关文章等内容

4024

2023.07.04

js删除节点的方法
js删除节点的方法

js删除节点的方法有:1、removeChild()方法,用于从父节点中移除指定的子节点,它需要两个参数,第一个参数是要删除的子节点,第二个参数是父节点;2、parentNode.removeChild()方法,可以直接通过父节点调用来删除子节点;3、remove()方法,可以直接删除节点,而无需指定父节点;4、innerHTML属性,用于删除节点的内容。

820

2023.09.01

JavaScript转义字符
JavaScript转义字符

JavaScript中的转义字符是反斜杠和引号,可以在字符串中表示特殊字符或改变字符的含义。本专题为大家提供转义字符相关的文章、下载、课程内容,供大家免费下载体验。

1716

2023.09.04

js生成随机数的方法
js生成随机数的方法

js生成随机数的方法有:1、使用random函数生成0-1之间的随机数;2、使用random函数和特定范围来生成随机整数;3、使用random函数和round函数生成0-99之间的随机整数;4、使用random函数和其他函数生成更复杂的随机数;5、使用random函数和其他函数生成范围内的随机小数;6、使用random函数和其他函数生成范围内的随机整数或小数。

3025

2023.09.04

如何启用JavaScript
如何启用JavaScript

JavaScript启用方法有内联脚本、内部脚本、外部脚本和异步加载。详细介绍:1、内联脚本是将JavaScript代码直接嵌入到HTML标签中;2、内部脚本是将JavaScript代码放置在HTML文件的`<script>`标签中;3、外部脚本是将JavaScript代码放置在一个独立的文件;4、外部脚本是将JavaScript代码放置在一个独立的文件。

3933

2023.09.12

Js中Symbol类详解
Js中Symbol类详解

javascript中的Symbol数据类型是一种基本数据类型,用于表示独一无二的值。Symbol的特点:1、独一无二,每个Symbol值都是唯一的,不会与其他任何值相等;2、不可变性,Symbol值一旦创建,就不能修改或者重新赋值;3、隐藏性,Symbol值不会被隐式转换为其他类型;4、无法枚举,Symbol值作为对象的属性名时,默认是不可枚举的。

2500

2023.09.20

Buffalo框架数据库开发全教程
Buffalo框架数据库开发全教程

本专题围绕Buffalo框架数据库开发,讲解database.yml多环境配置、soda与fizz迁移生成回滚、模型结构体标签、增删改查与条件查询、一对多与多对多关联、数据校验、回调钩子、事务处理及原生SQL执行能力。

0

2026.09.23

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WebStorm 官方调试文档
WebStorm 官方调试文档

共0课时 | 0人学习

React 教程
React 教程

共58课时 | 11.9万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 6.5万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn