Z
ZHANK

async/await

学习 async/await 语法、错误处理

async / await

async/await 是 ES2017 引入的语法糖,让异步代码看起来像同步代码。

学完本章你将: 掌握 async/await 语法与错误处理。


基本语法

javascript
// async 函数始终返回 Promise
async function greet() {
    return "Hello";
}
greet().then(msg => console.log(msg)); // "Hello"

// await 暂停执行直到 Promise 完成
async function fetchUser(id) {
    let response = await fetch(`/api/user/${id}`);
    let user = await response.json();
    return user;
}

错误处理

javascript
// try-catch
async function loadData() {
    try {
        let user = await fetchUser(1);
        let posts = await fetchPosts(user.id);
        console.log(posts);
    } catch (error) {
        console.error("出错了:", error.message);
    } finally {
        console.log("清理工作");
    }
}

// 或者 .catch()
async function loadData2() {
    let user = await fetchUser(1).catch(err => {
        console.error(err);
        return null;
    });
    if (!user) return;
    // ...
}

并发 vs 顺序

javascript
// 顺序执行(慢)
async function sequential() {
    let user = await fetchUser(1);   // 等 500ms
    let posts = await fetchPosts(1); // 等 500ms
    // 总共约 1000ms
}

// 并发执行(快)
async function concurrent() {
    let [user, posts] = await Promise.all([
        fetchUser(1),
        fetchPosts(1),
    ]);
    // 总共约 500ms
}

实战模式

javascript
// 1. 超时控制
async function fetchWithTimeout(url, timeout = 5000) {
    let controller = new AbortController();
    let timer = setTimeout(() => controller.abort(), timeout);
    try {
        let response = await fetch(url, { signal: controller.signal });
        return response.json();
    } finally {
        clearTimeout(timer);
    }
}

// 2. 重试机制
async function fetchWithRetry(url, retries = 3) {
    for (let i = 0; i < retries; i++) {
        try {
            return await fetch(url).then(r => r.json());
        } catch (err) {
            if (i === retries - 1) throw err;
            await new Promise(r => setTimeout(r, 1000 * (i + 1)));
        }
    }
}

// 3. 迭代异步
async function processArray(items) {
    for (let item of items) {
        await process(item); // 逐个处理
    }
}