JavaScript 异步编程详解

JavaScript 异步编程详解

JavaScript 是单线程语言,但通过异步编程机制,可以高效地处理 I/O 操作、网络请求等耗时任务。

回调函数 (Callback)

最传统的异步处理方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
function fetchData(callback) {
setTimeout(() => {
callback(null, { name: 'Alice', age: 25 });
}, 1000);
}

fetchData((err, data) => {
if (err) {
console.error('Error:', err);
return;
}
console.log('Data:', data);
});

回调地狱问题

1
2
3
4
5
6
7
8
// ❌ 回调地狱 - callback hell
getUserInfo(userId, (err, user) => {
getOrders(user.id, (err, orders) => {
getOrderDetails(orders[0].id, (err, details) => {
// 嵌套越来越深...
});
});
});

Promise

ES6 引入的 Promise 优雅地解决了回调地狱:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function fetchUser(id) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({ id, name: 'Alice' });
}, 1000);
});
}

// ✅ 链式调用
fetchUser(1)
.then(user => getOrders(user.id))
.then(orders => getOrderDetails(orders[0].id))
.then(details => console.log(details))
.catch(err => console.error(err));

Promise 常用方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 并行执行
Promise.all([fetchUser(1), fetchUser(2), fetchUser(3)])
.then(users => console.log('All users:', users));

// 竞速执行
Promise.race([fetchFromAPI1(), fetchFromAPI2()])
.then(result => console.log('Fastest:', result));

// 等待所有完成(包括失败)
Promise.allSettled([task1(), task2(), task3()])
.then(results => {
results.forEach(result => {
console.log(result.status, result.value || result.reason);
});
});

Async / Await

ES2017 带来了更直观的异步写法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
async function getUserData(userId) {
try {
const user = await fetchUser(userId);
const orders = await getOrders(user.id);
const details = await getOrderDetails(orders[0].id);
return details;
} catch (err) {
console.error('Error:', err);
throw err;
}
}

// 并行执行带 async/await
async function fetchAllUsers() {
const [user1, user2, user3] = await Promise.all([
fetchUser(1),
fetchUser(2),
fetchUser(3)
]);
return { user1, user2, user3 };
}

总结

方式 优点 缺点
Callback 简单直接 回调地狱
Promise 链式调用,可组合 代码仍有一定复杂度
Async/Await 代码最清晰 需要 try/catch

在实际开发中,推荐使用 async/await 配合 Promise 来处理异步操作,代码更清晰、易维护。


下一篇将介绍 JavaScript 事件循环机制,帮助你从原理层面理解异步编程!