JS 是单线程,同步代码从上往下跑,异步代码(定时器、AJAX)等同步完了再跑。
核心规则:
① 同步——立即执行,阻塞
② 异步——排队等同步完了再执行
③ event loop——调用栈空了才看任务队列
坑:setTimeout(fn, 0) 不是立即执行、Promise 比 setTimeout 先执行(微任务优先)、别搞混执行顺序。
// 1. JS 一个人干活,一次只能干一件事:同步代码从上往下先干完 // 2. 定时器这种异步活:得等同步全干完了才轮到 // 3. 就算你把延迟写成 0,它也不会立刻跑,照样得排队等同步走完
// 同步代码,立刻喊 A,第一个出来
console.log('A');
// 异步闹钟,定 0 毫秒,先去排队
setTimeout(function () { console.log('B'); }, 0);
// 同步代码,接着喊 C
console.log('C');
// 异步闹钟,定 100 毫秒,排在 B 后面
setTimeout(function () { console.log('D'); }, 100);
// 同步代码,再喊 E
console.log('E');
// 实际喊出来的顺序:A → C → E → B → D
// 一步一步看:
// ① 同步的 A、C、E 一口气全喊完
// ② 同步干完了,轮到排队的异步:B(0 毫秒)先响
// ③ D(100 毫秒)最后才响
看顺序先找同步代码,它们"插队"在前;异步里再按"延迟时间短的先执行"排队。
// 同步代码,立刻喊 1,第一个出来
console.log(1);
// 异步闹钟,先写的那个,排 1 号
setTimeout(function () { console.log(2); }, 0);
// 异步闹钟,后写的那个,排 2 号
setTimeout(function () { console.log(3); }, 0);
// 同步代码,接着喊 4
console.log(4);
// 实际喊出来的顺序:1 → 4 → 2 → 3
// 两个闹钟都定 0 毫秒:谁先写代码谁先响,不会乱插
同延迟的异步任务按"创建顺序"排队——先写的先跑,不会乱插。
// 记住这条流水线: // 同步代码 → 一口气全跑完 → 主线程空了 → 才轮到异步回调 // setTimeout(0) 不是"现在马上跑" // 而是"用最快速度排到异步队伍里等" // 既然要排队,就必须等前面同步代码全清场
把 setTimeout 想成"把纸条递给浏览器,等同步的事都办完再叫我"。作业③让你用自己的话写总结,说清"排队"两个字就得分。
| API | 作用 | 参数 | 返回值 | 代码示例 |
|---|---|---|---|---|
| console.log(x) | 同步代码,从上往下立刻打印 | 任意内容 | 无 | console.log('A'); // 立刻打印 |
| setTimeout(函数, 毫秒) | 异步排队,等同步全跑完才轮到 | 函数、毫秒 | 定时器 ID | setTimeout(function () { console.log('B'); }, 0); // 排队 |