大家好,我是程序员柏风,AI 最全的 Vibecoding 学习地图 http://coderoadmap.cn 作者。
异步深入
javascript-core 介绍 Promise 与 async/await;本课深入 事件循环、微任务/宏任务、回调地狱 与 fetch/XHR。Node 的 process.nextTick 与浏览器差异见 nodejs-essentials。
学习目标
- 画出 call stack、Web APIs、task queue 的关系
- 解释
setTimeout(0)与Promise.then的执行顺序 - 用 fetch 替代 XHR,并处理错误与超时
事件循环模型
┌─────────────┐ ┌──────────────┐ ┌─────────────────┐
│ Call Stack │ ←→ │ Web APIs │ → │ Callback Queue │
│ (同步代码) │ │ setTimeout等 │ │ (宏任务) │
└─────────────┘ └──────────────┘ └─────────────────┘
↓
┌─────────────────┐
│ Microtask Queue │
│ Promise.then 等 │
└─────────────────┘
每轮循环:执行一个宏任务 → 清空所有微任务 → 可能渲染 → 下一个宏任务。
经典输出顺序
console.log('A');
setTimeout(() => console.log('B'), 0);
Promise.resolve().then(() => console.log('C'));
queueMicrotask(() => console.log('D'));
console.log('E');
// A → E → C → D → B
async/await 中 await 之后的代码相当于微任务。
回调与 Promise 演进
// 回调风格(难维护)
getUser(id, (err, user) => {
if (err) return handle(err);
getOrders(user.id, (err2, orders) => {
if (err2) return handle(err2);
render(orders);
});
});
// Promise 链
getUser(id)
.then((user) => getOrders(user.id))
.then(render)
.catch(handle);
// async/await
async function load() {
try {
const user = await getUser(id);
const orders = await getOrders(user.id);
render(orders);
} catch (e) {
handle(e);
}
}
fetch 与错误处理
async function fetchTrack(slug) {
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 5000);
try {
const res = await fetch(`/api/tracks/${slug}`, {
signal: controller.signal,
});
if (!res.ok) {
throw new Error(`HTTP ${res.status}`);
}
return await res.json();
} finally {
clearTimeout(timeout);
}
}
fetch 只在网络失败时 reject;4xx/5xx 需手动检查 res.ok。
XHR(了解即可)
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/tracks');
xhr.onload = () => {
if (xhr.status === 200) console.log(JSON.parse(xhr.responseText));
};
xhr.send();
现代项目优先 fetch;旧库或上传进度场景仍可能见到 XHR。
与 React 数据加载
react-essentials 中 useEffect + async 函数需注意竞态:用 AbortController 或 ignore flag 取消过期请求。
练习
- 写 demo 验证微任务优先于
setTimeout(0) - 把一段嵌套回调改成
async/await - 用 fetch 请求 API,处理 404 与 abort 超时
小结
事件循环协调同步与异步;微任务先于宏任务;fetch 是现代 HTTP 默认选择。 下一课对象与原型。