如何处理异步代码中的错误

如何处理异步代码中的错误

Node.js中的异步代码是指不会阻塞其后代码执行的代码。在同步代码中,代码会等待当前操作完成后再执行后续代码,并且从上到下依次执行;而在异步代码中,异步代码会在单独的线程中执行,以使得后续代码的执行不会被阻塞,从而二者可以同时执行。要更深入地了解异步编程,请参考《JavaScript中的异步代码如何工作?》。

现在让我们讨论如何处理异步代码中的错误。

使用回调函数: 回调函数是作为异步函数的最后一个参数传递的函数,当异步函数执行完毕时会调用该回调函数。回调函数的第一个参数通常是错误对象,因此它们经常被称为 错误优先回调 。如果没有错误,错误对象将为null,否则它将包含有关错误的信息。

示例: 在下面的示例中,我们使用setTimeout方法使我们的mod函数成为异步函数。如果b为零,我们传递一个错误,说“不允许取模为零”,否则我们打印结果。这样,我们的回调函数每次调用mod函数时都会处理错误。

<script>
    const mod = (a, b, callback) => {
        setTimeout(() => {
            if (b == 0) {
                // Error 
                callback("Modulo zero is not allowed");
            } else {
                // Success
                callback(null, a % b);
            }
        }, 0);
    };
 
    // 5 mod 2 will give result 1
    mod(5, 2, (err, res) => {
        if (err) {
            console.log(err);
        }
        else {
            console.log('The result is ' + res);
        }
    });
 
    // 5 mod 0 will give error
    mod(5, 0, (err, res) => {
        if (err) {
            console.log(err);
        }
        else {
            console.log(`The result is ${res}`);
        }
    });
</script>

输出:

The result is 1
Modulo zero is not allowed

但是当我们使用回调方法时,有时会陷入回调地狱。为了避免这种情况,我们使用如下讨论的 Promise

使用Promise: Promise可以让我们在Nodejs中处理异步操作而不陷入回调地狱。一个Promise要么被解决,要么被拒绝。在Promise被解决或被拒绝之后,有两个方法 then()catch() 。如果被解决,那么then()方法中的代码将被执行,否则我们通过catch块抛出错误。

示例: 让我们修改上面的示例,并使用Promise处理错误。

<script>
    const mod = (a, b) => {
        return new Promise((resolve, reject) => {
            if (b == 0) {
                // Rejected (error)
                reject("Modulo zero is not allowed");
            } else {
                //Resolved (Success)
                resolve(a % b);
            }
        })
    };
 
    // 5 mod 2 will give result 1
    mod(5, 2).then((res) => {
        console.log(`The result is {res}`);
    }).catch((err) => {
        console.log(err);
    });
 
    // 5 mod 0 will give error
    mod(5, 0).then((res) => {
        console.log(`The result is{res}`);
    }).catch((err) => {
        console.log(err);
    });
</script>

输出:

The result is 1
Modulo zero is not allowed

代码现在比以前使用回调函数时更加清洁。虽然Promises使我们能够避免回调地狱,但它们自身有复杂的语法,因此我们引入了下面讨论的 异步 函数。

使用Async/Await: Async/Await使JavaScript Promises更易于使用。它使我们能够使用 try-catch 块处理错误。要使用async-await,我们只需创建一个async函数,在其中实现我们的try-catch块。在try块中,我们将等待我们的promise完成。如果它被解决了,我们将得到结果,否则将通过catch块抛出错误。await只能在async函数、异步回调或异步箭头函数内使用。

示例:

<script>
    const mod = (a, b) => {
        return new Promise((resolve, reject) => {
            if (b == 0) {
                // Rejected (error)
                reject("Modulo zero is not allowed");
            } else {
                //Resolved (Success)
                resolve(a % b);
            }
        });
    };
 
    // 5 mod 2 will give result 1
    async function _5mod2() {
        try {
            const res = await mod(5, 2);
            console.log(`The result of division is {res}`);
        } catch (err) {
            console.log(err);
        }
    };
    _5mod2();
 
    // 5 mod 0 will give error
    async function _5mod0() {
        try {
            const res = await mod(5, 0);
            console.log(`The result of division is{res}`);
        } catch (err) {
            console.log(err);
        }
    };
    _5mod0();
</script>

输出:

The result of division is 1
Modulo zero is not allowed

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程