JavaScript 异步编程
异步编程基础
同步与异步
// 同步代码console.log('开始');const result = doSomething();console.log('结果:', result);console.log('结束');
// 异步代码console.log('开始');doSomethingAsync().then(result => { console.log('结果:', result);});console.log('结束');
回调函数
// 基本回调示例function fetchData(callback) { setTimeout(() => { const data = { id: 1, name: 'JavaScript' }; callback(data); }, 1000);}
fetchData(data => { console.log('获取的数据:', data);});
// 回调地狱示例getUser(userId, user => { getOrders(user.id, orders => { getOrderDetails(orders[0].id, details => { console.log('订单详情:', details); }); });});
Promise
创建 Promise
const promise = new Promise((resolve, reject) => { // 异步操作 setTimeout(() => { const random = Math.random(); if (random > 0.5) { resolve('成功'); } else { reject('失败'); } }, 1000);});
promise .then(result => console.log(result)) .catch(error => console.error(error));
Promise 链式调用
function fetchUser(id) { return new Promise((resolve) => { setTimeout(() => { resolve({ id, name: 'Alice' }); }, 1000); });}
function fetchOrders(userId) { return new Promise((resolve) => { setTimeout(() => { resolve([{ id: 1, userId, product: 'Book' }]); }, 1000); });}
fetchUser(1) .then(user => fetchOrders(user.id)) .then(orders => console.log('订单:', orders)) .catch(error => console.error('错误:', error));
Promise.all 和 Promise.race
const promise1 = new Promise(resolve => setTimeout(() => resolve(1), 1000));const promise2 = new Promise(resolve => setTimeout(() => resolve(2), 2000));const promise3 = new Promise(resolve => setTimeout(() => resolve(3), 3000));
// 等待所有 Promise 完成Promise.all([promise1, promise2, promise3]) .then(results => console.log('全部完成:', results)) .catch(error => console.error('有一个失败:', error));
// 等待第一个完成的 PromisePromise.race([promise1, promise2, promise3]) .then(result => console.log('第一个完成:', result)) .catch(error => console.error('第一个失败:', error));
async/await
基本用法
async function fetchUserData() { try { const user = await fetchUser(1); const orders = await fetchOrders(user.id); console.log('用户订单:', orders); } catch (error) { console.error('错误:', error); }}
fetchUserData();
并行执行
async function fetchAllData() { try { const [users, products] = await Promise.all([ fetchUsers(), fetchProducts() ]); console.log('用户:', users); console.log('产品:', products); } catch (error) { console.error('错误:', error); }}
实际应用示例
class DataService { async fetchUserProfile(userId) { try { const user = await this.fetchUser(userId); const orders = await this.fetchOrders(user.id); const preferences = await this.fetchPreferences(user.id);
return { user, orders, preferences }; } catch (error) { console.error('获取用户资料失败:', error); throw error; } }
async fetchUser(id) { // 模拟 API 调用 return new Promise(resolve => { setTimeout(() => { resolve({ id, name: 'Alice' }); }, 1000); }); }
async fetchOrders(userId) { return new Promise(resolve => { setTimeout(() => { resolve([{ id: 1, userId, product: 'Book' }]); }, 1000); }); }
async fetchPreferences(userId) { return new Promise(resolve => { setTimeout(() => { resolve({ theme: 'dark', language: 'zh' }); }, 1000); }); }}
// 使用示例const service = new DataService();service.fetchUserProfile(1) .then(profile => console.log('用户资料:', profile)) .catch(error => console.error('错误:', error));
错误处理
Promise 错误处理
fetchData() .then(data => processData(data)) .then(result => saveData(result)) .catch(error => { console.error('发生错误:', error); // 错误恢复逻辑 return fallbackData; }) .finally(() => { // 清理工作 console.log('处理完成'); });
async/await 错误处理
async function processUserData() { try { const data = await fetchData(); const result = await processData(data); await saveData(result); } catch (error) { console.error('处理用户数据时出错:', error); // 错误处理逻辑 } finally { // 清理工作 }}
练习
- 实现一个简单的异步数据加载器
- 使用 Promise.all 同时获取多个 API 的数据
- 将回调式 API 转换为 Promise 式 API
小结
- 理解同步和异步编程的区别
- 掌握回调函数的使用和缺点
- 熟练使用 Promise 处理异步操作
- 掌握 async/await 的语法和应用
- 学会处理异步操作中的错误