Jupyter AI

31 异步编程与Promise ⏳之错误处理

📅 发表日期: 2024年9月14日

分类: 🟦TypeScript 入门

👁️阅读: --

在上篇中,我们学习了 async/await 的基本概念和用法。本篇将专注于如何在使用 Promiseasync/await 的过程中进行错误处理。异步编程的一个重要特性就是能够优雅地处理错误,这对构建健壮的应用程序至关重要。

Promise中的错误处理

Promise 的链式调用中,错误处理通常通过 .catch() 方法来实现。.catch() 方法可以捕获在 Promise 执行过程中出现的任何错误。

基本错误处理示例

function riskyOperation(): Promise<number> {
    return new Promise((resolve, reject) => {
        const success = Math.random() > 0.5; // 随机成功或失败
        if (success) {
            resolve(42);
        } else {
            reject(new Error("操作失败"));
        }
    });
}

riskyOperation()
    .then(result => {
        console.log(`操作成功,结果是: ${result}`);
    })
    .catch(error => {
        console.error(`发生了错误: ${error.message}`);
    });

在上面的示例中,riskyOperation 函数返回一个 Promise,该 Promise 可能会失败。在 .catch() 方法中,我们捕获了错误并进行了处理。

链式调用中的错误处理

当我们有多个 Promise 需要顺序执行时,如果其中一个 Promise 失败,后续的 .then() 不会被执行,这时我们依然可以使用 .catch() 来处理错误。

function fetchData(): Promise<number> {
    return new Promise((resolve, reject) => {
        // 模拟网络请求
        setTimeout(() => {
            const success = Math.random() > 0.5;
            if (success) {
                resolve(100);
            } else {
                reject(new Error("数据请求失败"));
            }
        }, 1000);
    });
}

fetchData()
    .then(data => {
        console.log(`获取的数据: ${data}`);
        return data * 2; // 继续处理数据
    })
    .then(result => {
        console.log(`处理后的结果: ${result}`);
    })
    .catch(error => {
        console.error(`错误: ${error.message}`);
    });

在上述示例中,我们使用 fetchData 函数模拟了一个数据请求。如果请求失败,错误会被捕获并处理,后续数据处理将会被跳过。

async/await中的错误处理

在使用 async/await 时,错误处理的方式更为直观和优雅。我们可以使用 try...catch 语句来处理异步操作中的错误。

基本错误处理示例

async function asyncRiskyOperation(): Promise<number> {
    if (Math.random() > 0.5) {
        return 42;
    } else {
        throw new Error("操作失败");
    }
}

async function main() {
    try {
        const result = await asyncRiskyOperation();
        console.log(`操作成功,结果是: ${result}`);
    } catch (error) {
        console.error(`发生了错误: ${error.message}`);
    }
}

main();

在这个例子中,我们在 async 函数中使用 try...catch 来捕获可能出现的错误。这样做的好处是使代码更加清晰易读。

包装多个异步操作的错误处理

当我们在一个异步函数中执行多个 await 操作时,单独的 try...catch 可以让我们处理每个操作的错误。

async function fetchAndProcessData() {
    try {
        const data = await fetchData();
        console.log(`获取的数据: ${data}`);
        const processedData = await processData(data);
        console.log(`处理后的结果: ${processedData}`);
    } catch (error) {
        console.error(`在处理数据时发生错误: ${error.message}`);
    }
}

async function processData(input: number): Promise<number> {
    if (Math.random() > 0.5) {
        return input * 2;
    } else {
        throw new Error("处理数据失败");
    }
}

fetchAndProcessData();

在这个例子中,fetchAndProcessData 函数中包含了对 fetchDataprocessDataawait 调用。如果其中任何一个操作失败,错误都会被捕获并输出相应的错误信息。

具体场景中的错误处理

在实际开发中,错误处理显得尤为重要,尤其是在进行网络请求或文件读取等操作时。我们可以通过细化错误处理的方式来提高代码的健壮性。

经典网络请求的错误处理

async function fetchUserData(userId: string): Promise<User> {
    try {
        const response = await fetch(`https://api.example.com/users/${userId}`);
        if (!response.ok) {
            throw new Error(`网络响应失败: ${response.statusText}`);
        }
        const userData = await response.json();
        return userData;
    } catch (error) {
        console.error(`获取用户数据失败: ${error.message}`);
        throw error; // 重新抛出错误,以便上层调用处理
    }
}

在这个示例中,我们对网络请求进行了详细的错误处理。如果网络响应失败,我们生成了一个详细的错误信息并抛出,使得调用这个函数的地方可以进一步处理错误。

小结

错误处理是异步编程中不可或缺的一部分。使用 Promise 时,我们可以用 .catch() 来捕获错误;在使用 async/await 时,try...catch 提供了更直观的方式来处理错误。确保我们能捕获并处理错误,可以让我们的代码更加健壮,也能提供更好的用户体验。

在下一篇中,我们将继续探讨如何并发处理多个 Promise,这是一个非常实用的技能,特别是在处理多个异步请求时。

🟦TypeScript 入门 (滚动鼠标查看)