回调函数是 JavaScript 中处理异步操作最基础的方式。
function fetchData(callback) {
setTimeout(() => {
const data = { id: 1, name: 'Example' };
callback(null, data); // 第一个参数通常用于错误
}, 1000);
}
fetchData((err, data) => {
if (err) {
console.error('Error:', err);
return;
}
console.log('Data received:', data);
});
当多个异步操作需要顺序执行时,代码会变得难以维护:
getData(function(a) {
getMoreData(a, function(b) {
getEvenMoreData(b, function(c) {
console.log('Final result:', c);
});
});
});
Promise 是 ES6 引入的异步编程解决方案,解决了回调地狱的问题。
function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const success = Math.random() > 0.5;
if (success) {
resolve({ id: 1, name: 'Promise Example' });
} else {
reject(new Error('Failed to fetch data'));
}
}, 1000);
});
}
fetchData()
.then(data => {
console.log('Success:', data);
return processData(data); // 返回新的 Promise
})
.then(processedData => {
console.log('Processed:', processedData);
})
.catch(err => {
console.error('Error:', err);
});
Promise.all()
: 等待所有 Promise 完成Promise.race()
: 返回最先完成的 PromisePromise.resolve()
/Promise.reject()
: 创建已解决/拒绝的 PromiseES2017 引入的语法糖,使异步代码看起来像同步代码。
async function getData() {
try {
const response = await fetchData(); // 等待 Promise 解决
const processed = await processData(response);
console.log('Final result:', processed);
} catch (error) {
console.error('Error occurred:', error);
}
}
getData();
async
函数总是返回 Promiseawait
只能在 async
函数中使用特性 | 回调函数 | Promise | async/await |
---|---|---|---|
可读性 | 差(回调地狱) | 较好 | 最好(类似同步代码) |
错误处理 | 手动(错误优先回调) | .catch() 方法 | try/catch 块 |
链式调用 | 困难 | 容易(.then() 链) | 非常容易 |
浏览器支持 | 所有版本 | ES6+ | ES2017+ |
现代 JavaScript 开发中,async/await 是处理异步操作的首选方式,它基于 Promise 构建,提供了更清晰、更易读的代码结构。