javascript-async
JavaScript 异步执行流程
核心概念
- JavaScript 是单线程的,一次只能做一件事
- 异步 = 不等待:发起操作 → 注册回调 → 干别的 → 结果回来执行回调
- 回调函数本身跟异步无关,只有交给宿主环境(setTimeout、I/O、网络、事件)延迟调用才是真正的异步
Event Loop(事件循环)
同步代码执行 → 清空所有微任务 → 取一个宏任务 → 清空所有微任务 → ...
| 类型 | 例子 | 优先级 |
|------|------|--------|
| 同步代码 | console.log, let a = 1 | 最高(先执行完) |
| 微任务 | Promise.then/catch/finally, queueMicrotask, MutationObserver | 次高(当前同步后立即清空) |
| 宏任务 | setTimeout, setInterval, setImmediate, I/O | 最低(每次只取一个) |
console.log('1')
setTimeout(() => console.log('2'), 0)
Promise.resolve().then(() => console.log('3'))
console.log('4')
// 输出:1 → 4 → 3 → 2
Promise
三种状态:pending(等待)→ fulfilled(成功)/ rejected(失败)
new Promise((resolve, reject) => {
resolve('成功')
// reject('失败')
})
.then(v => console.log(v))
.catch(e => console.error(e))
async/await
async function永远返回 Promise,无论函数体有没有await- 如果函数体内没有
await,函数体同步执行,返回值被包装成 Promise("同步执行 + 异步接口") - 函数体内有
await:暂停当前函数执行(不阻塞主线程),后续代码被切成微任务 - 函数内无
return时:返回Promise.resolve(undefined)
async function hello() { return "hello" }
console.log('A')
hello().then(v => console.log(v))
console.log('B')
// A → B → "hello"
async function hello() {
let c = 2
console.log(c)
await console.log(c) // await 即使跟非 Promise,也会把后续代码切成微任务
return c
}
console.log('1')
hello()
console.log('3')
// 1 → 2 → 3
Promise 并发
// 串行 — 一个一个等
const a = await task1()
const b = await task2() // task1 完成才执行
// 并行 — 同时发起,一起等
const [a, b] = await Promise.all([task1(), task2()])
Promise 静态方法
| 方法 | 行为 |
|------|------|
| Promise.all([p1, p2]) | 全成功才 resolve,一个失败就 reject |
| Promise.allSettled([p1, p2]) | 等所有完成,不关心成功还是失败 |
| Promise.race([p1, p2]) | 返回第一个完成的(不管成功还是失败) |
| Promise.any([p1, p2]) | 返回第一个成功的,全失败才 reject |
| Promise.resolve(v) | 包装一个值成 fulfilled Promise |
| Promise.reject(e) | 包装一个值成 rejected Promise |
await vs .then
| await | .then |
|-------|-------|
| 线性代码,像同步一样从上往下读 | 链式嵌套 |
| try/catch 统一处理 | 每个链挂 .catch |
| 变量直接赋值使用 | 必须在回调里才能访问 |
// .then
fetchUser().then(u => fetchPosts(u.id).then(p => console.log(p))).catch(e => ...)
// await
try {
const u = await fetchUser()
const p = await fetchPosts(u.id)
console.log(p)
} catch (e) { ... }
一句话总结
async声明该函数返回 Promise,await暂停当前函数等 Promise 完成并把后续代码切成微任务。Event Loop 按"同步 → 微任务 → 宏任务"的顺序执行,这就是 JavaScript 的异步执行流程。