zoukankan      html  css  js  c++  java
  • 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
    })()
  • 相关阅读:
    BERT在语义相似度计算中的应用(一)
    Debian 10.6 安装 oracle 19.3c 数据库database软件:传统的zip安装包
    Spring应用消费REST服务
    使用Spring Data自动创建repository实现及自动定义API实现
    SpringBoot中使用Spring profile进行配置【谨慎使用,参见SpringBoot 2.4.0发布文档】
    为SpringBoot声明配置属性的元数据
    【转】Winform中textBox通过正则表达式限制只能输入数字且是两位小数
    【转】WinForm中TextBox只能输入数字
    【转】C# winform窗体间传值(使用委托或事件)
    【转】Visual Studio2019报错/plugin.vs.js,行:1074,错误:缺少标识符、字符串或数字的解决方法
  • 原文地址:https://www.cnblogs.com/zzkxjh/p/12825808.html
Copyright © 2011-2022 走看看