Appearance
JavaScript 异步编程
什么是异步编程
JavaScript 是单线程语言,但通过异步编程可以处理非阻塞操作,提高程序性能。
回调函数(Callback)
基本概念
javascript
function fetchData(callback) {
setTimeout(() => {
const data = "获取到的数据";
callback(data);
}, 1000);
}
fetchData(function(result) {
console.log(result); // 1秒后输出:获取到的数据
});回调地狱问题
javascript
// 多层嵌套的回调,难以维护
getData(function(a) {
getMoreData(a, function(b) {
getEvenMoreData(b, function(c) {
// 更多嵌套...
});
});
});Promise
基本用法
javascript
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
const success = true;
if (success) {
resolve("操作成功");
} else {
reject("操作失败");
}
}, 1000);
});
promise
.then(result => console.log(result))
.catch(error => console.error(error));Promise 链式调用
javascript
fetchUserData()
.then(user => fetchUserPosts(user.id))
.then(posts => fetchPostComments(posts[0].id))
.then(comments => console.log(comments))
.catch(error => console.error(error));Promise.all 和 Promise.race
javascript
// 等待所有 Promise 完成
Promise.all([
fetchData1(),
fetchData2(),
fetchData3()
]).then(results => {
console.log("所有数据都获取完成:", results);
});
// 等待第一个 Promise 完成
Promise.race([
fetchData1(),
fetchData2()
]).then(result => {
console.log("第一个完成的结果:", result);
});async/await
基本语法
javascript
async function fetchData() {
try {
const result = await someAsyncOperation();
console.log(result);
} catch (error) {
console.error(error);
}
}实际应用示例
javascript
async function getUserProfile(userId) {
try {
const user = await fetch(`/api/users/${userId}`);
const userData = await user.json();
const posts = await fetch(`/api/users/${userId}/posts`);
const postsData = await posts.json();
return {
user: userData,
posts: postsData
};
} catch (error) {
console.error("获取用户资料失败:", error);
throw error;
}
}
// 使用
getUserProfile(123)
.then(profile => console.log(profile))
.catch(error => console.error(error));异步模式对比
| 方式 | 优点 | 缺点 |
|---|---|---|
| 回调函数 | 简单直接 | 回调地狱,难以维护 |
| Promise | 链式调用,错误处理 | 语法相对复杂 |
| async/await | 语法简洁,易读 | 需要现代浏览器支持 |
实际应用场景
1. 网络请求
javascript
async function loadUserData() {
const response = await fetch('/api/user');
const userData = await response.json();
return userData;
}2. 文件操作(Node.js)
javascript
const fs = require('fs').promises;
async function readFile() {
try {
const data = await fs.readFile('file.txt', 'utf8');
console.log(data);
} catch (error) {
console.error('读取文件失败:', error);
}
}3. 定时器
javascript
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function delayedOperation() {
console.log("开始操作");
await delay(2000);
console.log("操作完成");
}最佳实践
- 优先使用 async/await:语法更清晰
- 正确处理错误:使用 try-catch 或 .catch()
- 避免过度嵌套:合理使用 Promise.all()
- 考虑性能:避免不必要的串行操作
总结
异步编程是现代 JavaScript 开发的核心技能,掌握 Promise 和 async/await 可以让你写出更高效、更易维护的代码。
