• Async/Await处理错误


    async/await 优雅的错误处理

    const fetchData = () => {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve('fetch data is me')
            }, 1000)
        })
    }
    
    (async () => {
        try {
            const data = await fetchData()
            console.log('data is ->', data)
        } catch(err) {
            console.log('err is ->', err)
        }
    })()

    这么看,感觉倒是没什么问题,如果是这样呢?有多个异步操作,需要对每个异步返回的 error 错误状态进行不同的处理,以下是示例代码。

    const fetchDataA = () => {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve('fetch data is A')
            }, 1000)
        })
    }
    
    const fetchDataB = () => {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve('fetch data is B')
            }, 1000)
        })
    }
    
    const fetchDataC = () => {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve('fetch data is C')
            }, 1000)
        })
    }
    
    (async () => {
        try {
            const dataA = await fetchDataA()
            console.log('dataA is ->', dataA)
        } catch(err) {
            console.log('err is ->', err)
        }
    
        try {
            const dataB = await fetchDataB()
            console.log('dataB is ->', dataB)
        } catch(err) {
            console.log('err is ->', err)
        }
    
        try {
            const dataC = await fetchDataC()
            console.log('dataC is ->', dataC)
        } catch(err) {
            console.log('err is ->', err)
        }
    })()

    这样写代码里充斥着 try/catch,有代码洁癖的你能忍受的了吗?这时可能会想到只用一个 try/catch。

    // ... 这里 fetch 函数省略
    
    (async () => {
        try {
            const dataA = await fetchDataA()
            console.log('dataA is ->', dataA)
            const dataB = await fetchDataB()
            console.log('dataB is ->', dataB)
            const dataC = await fetchDataC()
            console.log('dataC is ->', dataC)
        } catch(err) {
            console.log('err is ->', err)
            // 难道要定义 err 类型,然后判断吗??
            /**
             * if (err.type === 'dataA') {
             *  console.log('dataA err is', err)
             * }
             * ......
             * */
        }
    })()

    如果是这样写只会增加编码的复杂度,而且要多写代码,这个时候就应该想想怎么优雅的解决,async/await 本质就是 promise 的语法糖,既然是 promise 那么就可以使用 then 函数了。

    (async () => {
        const fetchData = () => {
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    resolve('fetch data is me')
                }, 1000)
            })
        }
    
        const data = await fetchData().then(data => data ).catch(err => err)
        console.log(data)
    })()

    在上面写法中,如果 fetchData 返回 resolve 正确结果时,data 是我们要的结果,如果是 reject 了,发生错误了,那么 data 是错误结果,这显然是行不通的,再对其完善。

    (async () => {
        const fetchData = () => {
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    resolve('fetch data is me')
                }, 1000)
            })
        }
    
        const [err, data] = await fetchData().then(data => [null, data] ).catch(err => [err, null])
        console.log('err', err)
        console.log('data', data)
        // err null
        // data fetch data is me
    })()

    这样是不是好很多了呢,但是问题又来了,不能每个 await 都写这么长,写着也不方便也不优雅,再优化一下。

    (async () => {
        const fetchData = () => {
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    resolve('fetch data is me')
                }, 1000)
            })
        }
    
        // 抽离成公共方法
        const awaitWrap = (promise) => {
            return promise
                .then(data => [null, data])
                .catch(err => [err, null])
        }
    
        const [err, data] = await awaitWrap(fetchData())
        console.log('err', err)
        console.log('data', data)
        // err null
        // data fetch data is me
    })()
  • 相关阅读:
    [转]oracle 10g数据泵之impdp-同时导入多个文件
    IMP数据到指定的表空间
    [转]Oracle数据泵的使用
    [转]oracle pump expdp impdp使用
    liunx 安装ActiveMQ 及 spring boot 初步整合 activemq
    安装本地jar包到仓库
    centos7.4 64位安装 git
    出现 CannotAcquireLockException 异常
    centos7.4 64位安装 redis-4.0.0
    java代码定时备份mysql数据库及注意事项——基于 springboot
  • 原文地址:https://www.cnblogs.com/zzkxjh/p/12825808.html
Copyright © 2020-2023  润新知