async/await 异常捕获更优雅的处理方式

1.async函数中为什么需要捕获异常?

任何一个await语句后面的 Promise 对象变为reject状态,那么整个async函数都会中断执行。有时,我们希望即使前一个异步操作失败,也不要中断后面的异步操作。这时可以将第一个await放在try...catch结构里面,这样不管这个异步操作是否成功,第二个await都会执行。

那么也意味着并不是所有的async函数中都需要使用trycatch。比如,有这样一个场景,项目中写了一个定时刷新列表的异步任务,如果刷新成功,则提示用户:数据已于XXX时间更新成功。此时,如果使用了try...catch,则会出现接口刷新失败,也会提示用户数据刷新成功。

js 复制代码
  enableLoopTask(){
      if(this.timerId) clearInterval(this.timerId)
      this.timerId = setInterval(()=>{
        this.loadData()
        const refreshTime = moment(Date.now()).format("YYYY-MM-DD HH:mm:ss")
        this.$message.success(`当前列表数据已于${refreshTime}更新成功,请查看!`);
      },1000 * 5)
    },
    // 点击查询时判断是否是当天,是当天 需要间隔30min刷新一次数据
    searchQuery() {
      this.queryParams = Object.assign({},this.formData)
      this.loadData()
      const isEnable = this.formData.businessDate === today
      if(!isEnable) {
        clearInterval(this.timerId)
        return
      }
      this.enableLoopTask()
    },

2.什么情况下需要处理异常

2.1多个异步请求串行

js 复制代码
try {  
  // 获取列表list  
  const list = await getList(params)  
  // 获取单个详情  
  const info = await getListById(list[0]?.id)  
} catch {}

2.2处理异步请求的 loading 状态

js 复制代码
try { 
  this.loading = true
  // 获取列表list  
  const list = await getList(params)  
} finally {  
  this.loading = false  
}

如果请求接口失败就想一直loading,那就另外处理了。因为await 命令后面的函数本身是一个promise,所以上面的也可以直接使用catch,如下:

js 复制代码
this.loading = true  
let res = await getList().catch(() => (this.loading = false))  
if (!res) return

3.那怎么避免项目中大量的try-catch~呢?

js 复制代码
   /**
         * @param { Promise } promiseFn
         * @param { Object= } errorExt - Additional Information you can pass to the err object
         * @return { Promise }
         */
  function fetchAsyncTuple(promiseFn,errorExt){
        return promiseFn.then(res=>{
            return [res,null]
        }).catch(error=>{
            if(errorExt) {
                const combineError = Object.assign({},error,errorExt)
                return combineError
            }  
            return [undefined,error]     
       })
   }

优化后,业务中直接这样类似这样使用:

js 复制代码
    async getProjectInfoList(params) {
      this.infoListLoading = true;
      if (params === 1) {
        this.paginationProps.page = 1;
      }
     const [data,error] =await fetchAsyncTuple(fetchProjectInfoList(this.queryParams))
     if(!error){
        this.paginationProps.total = data.data.page.totalCount;
        this.tableData = data.data.page.list;
        this.infoListLoading = false;
     } 
    },

没优化前是这样的:

js 复制代码
  async getProjectInfoList(params) {
      this.infoListLoading = true;
      if (params === 1) {
        this.paginationProps.page = 1;
      }
      try {
        const res = await fetchProjectInfoList(this.queryParams);
        this.paginationProps.total = res.data.page.totalCount;
        this.tableData = res.data.page.list;
        this.infoListLoading = false;
      } catch (error) {
        console.error("error---", error);
      } finally {
        this.infoListLoading = false;
      }
 },

或者这样是否也可以呢?

js 复制代码
   const fetchAsyncTuple = async (promiseCallback) => {
        try {
            const res = await promiseCallback
            if (res) {
                return [res, null]
            }
        } catch (error) {
            return [null, error]
        }
   }
相关推荐
choke23312 小时前
[特殊字符] Python 文件与路径操作
java·前端·javascript
云飞云共享云桌面12 小时前
高性能图形工作站的资源如何共享给10个SolidWorks研发设计用
linux·运维·服务器·前端·网络·数据库·人工智能
Deng94520131413 小时前
Vue + Flask 前后端分离项目实战:从零搭建一个完整博客系统
前端·vue.js·flask
威迪斯特13 小时前
Flask:轻量级Web框架的技术本质与工程实践
前端·数据库·后端·python·flask·开发框架·核心架构
wuhen_n13 小时前
JavaScript内置数据结构
开发语言·前端·javascript·数据结构
大鱼前端13 小时前
为什么我说CSS-in-JS是前端“最佳”的糟粕设计?
前端
不爱吃糖的程序媛13 小时前
Capacitor:跨平台Web原生应用开发利器,现已全面适配鸿蒙
前端·华为·harmonyos
AC赳赳老秦13 小时前
2026国产算力新周期:DeepSeek实战适配英伟达H200,引领大模型训练效率跃升
大数据·前端·人工智能·算法·tidb·memcache·deepseek
CHU72903513 小时前
淘宝扭蛋机抽盒小程序前端功能解析:解锁趣味抽盒新体验
前端·小程序
-凌凌漆-13 小时前
【npm】npm的-D选项介绍
前端·npm·node.js