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() 方法)

posted @ 2025-11-07 15:54  冀未然  阅读(0)  评论(0)    收藏  举报