Javascrip 之 await fetch()
Javascrip 之 await fetch()
await fetch()怎么理解?
await fetch() 是 JavaScript 中用于处理网络请求的现代语法。
1. 基础概念
fetch() 函数
是浏览器内置的 API,用于发起 HTTP 请求
返回一个 Promise 对象
替代了传统的 XMLHttpRequest
await 关键字
用于等待 Promise 完成
只能在 async 函数中使用
让异步代码看起来像同步代码
2. 基本语法
// 基本格式
const response = await fetch(url, options);
const data = await response.json();
3. 实际示例
示例 1:GET 请求(获取数据)
async function getUserData() {
try {
// 等待 fetch 完成,获取响应对象
const response = await fetch('https://api.example.com/users/1');
// 检查响应状态
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
// 等待响应体解析为 JSON
const userData = await response.json();
console.log(userData);
return userData;
} catch (error) {
console.error('请求失败:', error);
}
}
示例 2:POST 请求(创建数据)
async function createUser(userData) {
try {
const response = await fetch('https://api.example.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(userData), // 将对象转为 JSON 字符串
});
if (!response.ok) {
throw new Error(`创建失败: ${response.status}`);
}
const newUser = await response.json();
return newUser;
} catch (error) {
console.error('创建用户失败:', error);
}
}
// 使用示例
const user = {
name: '张三',
email: 'zhangsan@example.com',
age: 25
};
createUser(user);
4. 与传统回调方式的对比
传统方式(回调地狱)
// 使用 XMLHttpRequest
function getUsers(callback) {
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/users');
xhr.onload = function() {
if (xhr.status === 200) {
callback(null, JSON.parse(xhr.responseText));
} else {
callback(new Error('请求失败'));
}
};
xhr.onerror = function() {
callback(new Error('网络错误'));
};
xhr.send();
}
// 使用回调
getUsers(function(error, users) {
if (error) {
console.error(error);
return;
}
console.log(users);
});
现代方式(async/await)
async function getUsers() {
try {
const response = await fetch('/api/users');
if (!response.ok) throw new Error('请求失败');
const users = await response.json();
return users;
} catch (error) {
console.error(error);
}
}
// 使用方式
const users = await getUsers();
console.log(users);
5. fetch() 的响应对象
fetch() 返回的响应对象包含:
const response = await fetch(url);
// 常用属性
console.log(response.status); // HTTP 状态码,如 200, 404
console.log(response.statusText); // 状态文本,如 "OK", "Not Found"
console.log(response.ok); // 布尔值,表示请求是否成功 (200-299)
console.log(response.headers); // 响应头信息
// 常用方法(返回 Promise)
const text = await response.text(); // 获取文本
const json = await response.json(); // 获取 JSON
const blob = await response.blob(); // 获取二进制数据
6. 完整的 CRUD 操作示例
class ApiService {
constructor(baseURL) {
this.baseURL = baseURL;
}
// GET - 获取所有用户
async getAllUsers() {
const response = await fetch(`${this.baseURL}/users`);
if (!response.ok) throw new Error('获取用户列表失败');
return await response.json();
}
// GET - 根据ID获取用户
async getUserById(id) {
const response = await fetch(`${this.baseURL}/users/${id}`);
if (!response.ok) throw new Error(`用户 ${id} 不存在`);
return await response.json();
}
// POST - 创建用户
async createUser(userData) {
const response = await fetch(`${this.baseURL}/users`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(userData),
});
if (!response.ok) throw new Error('创建用户失败');
return await response.json();
}
// PUT - 更新用户
async updateUser(id, userData) {
const response = await fetch(`${this.baseURL}/users/${id}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(userData),
});
if (!response.ok) throw new Error('更新用户失败');
return await response.json();
}
// DELETE - 删除用户
async deleteUser(id) {
const response = await fetch(`${this.baseURL}/users/${id}`, {
method: 'DELETE',
});
if (!response.ok) throw new Error('删除用户失败');
return { success: true, id };
}
}
// 使用示例
const api = new ApiService('http://localhost:3000');
async function example() {
try {
// 创建用户
const newUser = await api.createUser({
name: '李四',
email: 'lisi@example.com'
});
console.log('创建的用户:', newUser);
// 获取所有用户
const users = await api.getAllUsers();
console.log('所有用户:', users);
// 更新用户
const updatedUser = await api.updateUser(newUser.id, {
name: '李四(更新)',
email: 'lisi_updated@example.com'
});
console.log('更新的用户:', updatedUser);
// 删除用户
const result = await api.deleteUser(newUser.id);
console.log('删除结果:', result);
} catch (error) {
console.error('操作失败:', error);
}
}
example();
7. 错误处理最佳实践
async function safeFetch(url, options = {}) {
try {
const response = await fetch(url, options);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
return await response.json();
} catch (error) {
// 网络错误或解析错误
console.error('Fetch 错误:', error);
throw error; // 重新抛出让调用者处理
}
}
// 使用
try {
const data = await safeFetch('/api/users');
console.log(data);
} catch (error) {
// 统一错误处理
alert('数据加载失败,请重试');
}
总结
await fetch() 的核心优势:
代码简洁:避免了回调地狱
错误处理统一:使用 try-catch 处理所有错误
可读性强:异步代码看起来像同步代码
现代标准:是当前处理网络请求的推荐方式
理解 await fetch() 的关键是明白它在等待两个异步操作:
网络请求完成(获取响应对象)
数据解析完成(如 .json() 方法)
浙公网安备 33010602011771号