异步编程模型里的异常处理链条

866 阅读2分钟

对于同步的异常,如何处理

function fun1() {
    try {
        fun2()
    } catch (error) {
        console.log('error');
    }
}
function fun2() {
    try {
        fun3()
    } catch (error) {
        console.log('error');
    }
}
function fun3() {
    try {
        throw new Error();
    } catch (error) {
        console.log('error');
    }
}

fun1()

但是这种 try catch 只是对同步的方法有效果的,如果说这个方法内部包含有一些异步的操作的话,实际上try catch 有时候是捕捉不到异常的

function fun1() {
    try {
        fun2()
    } catch (error) {
        console.log('error');
    }
}
function fun2() {
    try {
        fun3()
    } catch (error) {
        console.log('error');
    }
}
function fun3() {
    setTimeout(function () {
        throw new Error()
    }, 1000);
}

fun1()

结果是 异常还是被抛出,没有打印出error

所以当我们的函数调用链中 如果有异步的操作的话,我们如何这样一个异常处理?

async await 为 promise的语法糖

function fun1() {
    try {
        fun2()
    } catch (error) {
        console.log('error');
    }
}
async function fun2() {
    try {
        await fun3()
    } catch (error) {
        console.log('error');
    }
}
async function fun3() {
    return await setTimeout(function() {
        throw new Error();
    })
}
fun1()

发现异常还是没有被捕捉到 ==原因:这里return 回去的promise 是不对的,我们要return 的promise 是要对这个function的promise包装,必须返回的是这个异步函数的 promise 包装==

正确写法

function fun1() {
    try {
        fun2()
    } catch (error) {
        console.log('error');
    }
}
async function fun2() {
    try {
        await fun3()
    } catch (error) {
        console.log('error');
    }
}
function fun3() {
    return new Promise((resolve, reject) => {
        setTimeout(function() {
            reject('cuo wu')
        },1000)
    })
}
fun1()

总结:

当我们函数调用中 存在异步的操作时 我们如何捕获异常 不能通过一味的 try catch 重点: 异步编程模型的异常处理链条

async await那个加上return的问题在于,await作用在于求值,所以返回的promise,包装的是那个值,不是那个异步函数。 所以,要想捕获道错误,必须返回的是 promise包装的那个函数

结论: 某一个函数返回给了你一个 promise(这个promise 必须返回的是这个异步函数的包装) ,那么在其他函数调用的时候,你加上一个await。加上await之后就可以try catch

这种方法用于处理函数异步函数调用的异常处理