什么是异步编程?
JavaScript 是单线程语言,但通过异步编程可以处理耗时操作(如网络请求、文件读取)而不阻塞主线程。
回调函数
回调函数是异步编程的基础:
function fetchData(callback) {
setTimeout(() => {
callback('数据加载完成');
}, 1000);
}
fetchData(function(data) {
console.log(data);
});
回调地狱
多层嵌套的回调会导致代码难以维护:
doSomething(function(result) {
doMore(result, function(newResult) {
doMore(newResult, function(finalResult) {
console.log(finalResult);
});
});
});
Promise
Promise 是处理异步操作的更优雅方式。
创建 Promise
const promise = new Promise((resolve, reject) => {
// 异步操作
setTimeout(() => {
const success = true;
if (success) {
resolve('操作成功');
} else {
reject('操作失败');
}
}, 1000);
});
使用 Promise
promise
.then(result => {
console.log(result);
return '链式调用';
})
.then(data => {
console.log(data);
})
.catch(error => {
console.error(error);
});
Promise 静态方法
Promise.all() - 等待所有 Promise 完成
Promise.all([promise1, promise2, promise3])
.then(results => {
console.log(results); // [result1, result2, result3]
});
Promise.race() - 返回最先完成的 Promise
Promise.race([promise1, promise2])
.then(result => {
console.log(result); // 最先完成的结果
});
Async/Await
async/await 是基于 Promise 的语法糖,让异步代码看起来像同步代码。
基本用法
async function fetchData() {
try {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
console.log(data);
} catch (error) {
console.error(error);
}
}
箭头函数
const fetchData = async () => {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
return data;
};
并行执行
async function fetchMultipleData() {
const [users, posts, comments] = await Promise.all([
fetch('/api/users').then(res => res.json()),
fetch('/api/posts').then(res => res.json()),
fetch('/api/comments').then(res => res.json())
]);
return { users, posts, comments };
}
错误处理
Try-Catch
async function handleRequest() {
try {
const response = await fetch('/api/data');
const data = await response.json();
return data;
} catch (error) {
console.error('请求失败:', error);
throw error;
}
}
多个 Promise 错误处理
const results = await Promise.allSettled([
fetchData1(),
fetchData2(),
fetchData3()
]);
results.forEach(result => {
if (result.status === 'fulfilled') {
console.log(result.value);
} else {
console.error(result.reason);
}
});
最佳实践
- 优先使用 async/await 而不是 .then()
- 总是使用 try-catch 处理错误
- 使用 Promise.all 进行并行请求
- 避免在循环中使用 await(使用 Promise.all 代替)
学习资源
点评
请文明点评
加载评论中...
编辑此页 或