async_await异常捕获

news2024/10/6 2:29:28

写在前面

不知道大家项目里面是怎么处理 async/await 的异常,我斗胆在我们项目里翻了一下,发现大量使用 try-catch 来处理 async/await 异常。

try-awati-catch.png

首先说明一下, try-catch 处理并没有什么问题,我只是觉得这么写代码会有点乱,感觉代码逻辑像是断层了一样,不易理解;

其次是代码冗余问题,单个 try-catch 就占了好几行代码,如果每个请求的地方都添加 try-catch,就会显得代码很臃肿。
而对于这种大量相同的冗余代码,完全可以用一种通用的函数来替代。

async/await 是在 ES2017 中引入的,目的是为了让异步操作更加直观、方便,同时也解决了 Promise 的回调地狱问题。想必这些概念大家都已经了解了,那么我们为什么要捕获 async/await 的异常呢?它们是在什么时候发生异常呢? 带着问题我们一起看一下本文。

什么时候会请求异常

我们都知道 await 后面一般都是异步请求,异步请求发生异常的原因大致有以下几种:

  1. 网络问题导致,网络断开连接,请求不到;
  2. 网络慢导致异步请求超时。

什么情况下需要处理请求异常

一旦有以上情况出现,这个异步请求就会产生异常,而 JavaScript 又是一个单线程语言,代码报错后就会导致后面的代码无法继续执行,所以此时就需要添加 try-catch 来捕获异步请求的异常,使得代码可以继续向后执行。

但有必要为所有的异步请求都加 try-catch 吗?

我研究了下我们项目的代码,异步请求加了 try-catch 处理的,有以下几种情况:

多个异步请求串行

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

前一个异步请求的返回结果,会作为后一个异步请求的请求参数使用,所以一旦前一个请求异常,后面的请求肯定会异常,所以需要添加 try-catch 处理。

处理异步请求的 loading 状态

loading.value = true
try {
  // 获取列表list
  const list = await getList(params)
} finally {
  loading.value = false
}

一般我们处理异步请求前,会为其添加 loading 状态,而一旦请求异常出现时,如果不加 try-catch 时就会导致页面一直处于 loading 状态。所以需要在finally中将 loading 状态置为 false,catch中处理时需要外部再处理一次

那么,我们如何优雅的处理异步请求中的 try-catch 呢?

处理方法

使用 Promise 处理

首先需要明确一点:正常情况下,await 命令后面是一个 Promise 对象。所以它本身就可以使用.catch来捕获异常,那么像上面第二种只是处理 loading 状态的操作,完全可以在.catch进行处理,然后用if判断来控制提前退出,没必要写 try-catch 这种冗余代码。

loading.value = true
let res = await getList().catch(() => (loading.value = false))
if (!res) return
// 请求成功后正常操作

await-to-js 处理函数

简单的异步请求我们可以使用上面这种方法,但遇到多个异步操作时,就需要借助我们今天要说的await-to-js这个库,它的介绍很简单:无需 try-catch 即可轻松处理错误

而且源码贼简单,就 23 行代码,我们一起来看看。

/**
 * @param { Promise } promise
 * @param { Object= } errorExt - Additional Information you can pass to the err object
 * @return { Promise }
 */
export function to<T, U = Error>(
  promise: Promise<T>,
  errorExt?: object
): Promise<[U, undefined] | [null, T]> {
  return promise
    .then<[null, T]>((data: T) => [null, data])
    .catch<[U, undefined]>((err: U) => {
      if (errorExt) {
        const parsedError = Object.assign({}, err, errorExt)
        return [parsedError, undefined]
      }

      return [err, undefined]
    })
}

export default to

大致流程如下:
函数to接受参数PromiseerrorExt,如果这个 Promise 成功时返回[null, data],如果异常时会判断是否带有errorExt参数(代表传递给 err 对象的附加信息),如果有时会与 catch 捕获的 err 合并返回,如果没有时返回[err, undefined]

很简单的逻辑是不是,接着我们看下它的用法:

  • 安装

    # use npm
    npm i await-to-js --save
    # use yarn
    yarn add await-to-js
    
  • 使用

    首先引入to函数,可以看到包很小,只有 370b,gzip 压缩后只有 242b,所以放心引入,别担心什么包大小问题。

    await-to-js-size.png

    我们通过to来改写一下上面第一种问题:

    import to from 'await-to-js'
    
    // 获取列表list
    const [err, data] = await to(getList(params))
    if (err) return
    // 获取单个详情
    const info = await to(getListById(list[0]?.id))
    

    通过to函数改造后,如果返回第一个参数不为空时,说明该请求报错,就可以提前 return 出去,如果不存在第一个参数时,则异步请求成功。

总结

本文通过研究 async/await 的异常捕获,发现了两种常见的异步请求异常捕获,并提出了两种简单的解决方法。通过这两种方法,就可以丢掉冗余的 try-catch,然后你就会发现没了 try-catch 的代码看起来都是顺眼的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/666213.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何设计一个高效的分布式日志服务平台

作者 | 百度智能小程序团队 导读 本文首先介绍了分布式服务下日志服务建设的挑战&#xff0c;然后介绍了下业内ELK的通用解决方案及与天眼日志服务的差异性&#xff0c;接下来详细介绍了天眼日志服务平台的整体架构&#xff0c;如何做采集、传输、检索、隔离、清理等机制的&…

自定义element-table列表展示(可设置按钮权限)

<template><!-- 二次封装表格&#xff0c; 仅支持单选 :style"{ height: height }"--><div class"self_table"><el-table:data"tableData"style"width: 100%"v-loading"loading"stripeselection-chang…

苹果手机备份占内存吗 苹果手机备份到电脑怎么操作

苹果手机备份占内存吗&#xff1f;实际上&#xff0c;苹果手机备份并不占用本机内存。在使用苹果手机的过程中&#xff0c;备份是一个必要的操作&#xff0c;可以避免丢失重要的数据或者恢复丢失的数据。但是有些用户可能会担心备份会占用手机的内存&#xff0c;从而影响手机的…

统信UOS系统开发笔记(五):安装QtCreator开发IDE中的中文输入环境Fcitx输入法

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/131302096 红胖子(红模仿)的博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软…

MySQL 日志管理、备份与恢复

目录 一、 MySQL日志管理1.1 日志的分类1.1.1 错误日志1.1.2 通用查询日志1.1.3 二进制日志1.1.4 慢查询日志1.1.5 配置日志 1.2 日志的查询 二、数据库备份的分类2.1 数据备份的重要性2.2 数据库备份的分类2.3 常用的备份方法2.4 MySQL完全备份2.4.1 mysql完全备份2.4.2 mysql…

【FPGA入门】第五篇、按键消抖

目录 第一部分、按键抖动现象 第二部分、消抖思路及代码 1、简单的按键消抖思路 2、实际按键消抖思路 3、实际按键消抖模块代码 第三部分、总结 第一部分、按键抖动现象 只要学习过单片机的都会知道&#xff0c;按键在按下去和松开的那个瞬间都存在抖动&#xff0c;在单片…

玩转AI绘图 电脑配置怎么选?

大家好&#xff0c;我是权知星球&#xff0c;很多小伙伴留言想了解一下AI绘图相关知识&#xff0c;那么&#xff0c;想要玩转AI绘图&#xff0c;电脑配置该怎么选呢&#xff1f; 首先我们了解一下什么叫AI绘图&#xff1f; AI绘图指的是利用人工智能技术实现的自动绘图&#x…

小白到运维工程师自学之路 第三十七集 (mha高可用集群)

一、概述 MHA&#xff08;Master High Availability&#xff09;是一个开源的MySQL高可用性解决方案&#xff0c;它可以自动监测MySQL主节点的状态&#xff0c;并在主节点发生故障时自动将从节点提升为新的主节点&#xff0c;从而实现MySQL的高可用性。MHA集群通常由多个MySQL实…

C++基础(7)——类和对象(5)

前言 本文主要介绍C中的继承 4.6.1&#xff1a;继承和继承方式&#xff08;公有、保护、私有&#xff09; 4.6.2&#xff1a;继承中的对象模型&#xff0c;sizeof()求子类对象大小 4.6.3&#xff1a;子类继承父类后&#xff0c;两者构造和析构顺序 父类先构造、子类先析构 如…

一道SQL Server窗口函数的面试题

概要 本文介绍一道和SQL Server窗口函数相关的面试题&#xff0c;主要涉及窗口函数的原理和Framing参数的设置。 设计和实现 题目介绍 输入数据如下&#xff1a; 主要包括账户编号&#xff08;account_no&#xff09;&#xff0c;交易日期&#xff08;tran_date&#xff0…

Win10下旧移动硬盘设备USB3.0异常

旧USB3.0硬盘盒设备在WIN10下的异常情况&#xff0c;通过慢插入、快插入的方式进行工作模式的选择&#xff0c;其中在USB3.0的情况下&#xff0c;读写工作异常。 1、测试硬盘盒 商品名称&#xff1a;Iomega Prestige Disktop Hard Drive,USB 3.0 购买日期&#xff1a;2012年…

Ubuntu20.04显卡驱动安装的完整过程(超详细)

1、首先查看硬件&#xff1a;显卡是否安装 lspci | grep -i vga lspci | grep -i nvidia 注意&#xff1a;如果没显示显卡信息则看显卡是否安装好&#xff08;看下显卡风扇是否在转&#xff0c;图中是显卡位置&#xff09;&#xff0c;然后再执行上面的命令. 确定显卡安装没问…

Linux基础(一)—— 什么是Linux系统?和Windows区别在哪?常见的安装方式【新星计划Linux】

#2023 博客之星–城市之星领跑者活动开启# 文章目录 01 | Linux的特点02 | Linux 和 Windows03 | Linux的种类04 | Linux的安装方式 Linux 是一种自由和开放源代码的 Unix 操作系统&#xff0c;其内核是由林纳斯托瓦兹在1991年开始编写。Linux 操作系统采用了 GNU 项目的许多组…

【深度学习】4-3 误差反向传播法 - Affine/Softmax层的实现

Affine层 神经网络的正向传播中进行的矩阵的乘积运算(也就是Y np.dot(X, W) B)在几何学领域被称为“仿射变换”。因此&#xff0c;这里将进行仿射变换的处理实现为“Affine层”。 几何中&#xff0c;仿射变换包括一次线性变换和一次平移&#xff0c;分别对应神经网络的加权…

自由软件,自由社会之GNU 操作系统的初始公告

导读这是 GNU 工程的原始通告&#xff0c;由理查德斯托曼于 1983 年 9 月 27 日发表。纵观历史&#xff0c;可以发现 GNU 工程在很多地方都与这份初始通告有很多差异。比如实际是拖延到了 1984 年 1 月才开始。而自由软件的很多哲学理念也是数年之后才得以厘清。 From mit-vax!…

阿里云学生验证网页及申请认证流程

阿里云学生用户完成学生认证可以领取一台阿里云服务器&#xff0c;那么问题来了&#xff0c;阿里云学生验证申请入口​在哪&#xff1f;阿里云百科分享阿里云学生验证入口网页链接及学生认证全流程&#xff1a; 目录 阿里云学生验证入口及申请流程 打开学生验证申请入口 支…

周大福荣获2023亚洲零售大奖——年度珠宝零售商

由成立于1991年、服务于亚洲充满活力的零售业的行业杂志—《亚洲零售杂志》主办的“2023亚洲零售大奖”评选结果于6月15日揭晓&#xff0c;周大福珠宝集团凭借创新和卓越的表现荣获“2023亚洲零售大奖—年度珠宝零售商&#xff08;中国&#xff09;”&#xff0c;是中国唯一入榜…

产品经理面试常见的25个必问题(二)

14、举例分析你知道的几种商业模式和盈利模式&#xff1f; 先明确商业模式和盈利模式的不同。 1)、商业模式有很多种&#xff0c;但基本分为三类&#xff1a; ●以客户驱动的商业模式&#xff0c;多是代理大厂商产品为主&#xff0c;以营销客户赚差价和服务费为主&#xff1…

GPT提示词系统学习-第四课-好玩的角色指令-效果简直是YYDS了

开篇 各位奇思妙想的程序伙伴们,如果你还未加入GPT万能生成器的狂欢队伍,那现在正是时候!让我来带你短暂探访一下GPT惊艳的角色创建功能。嘘~让我们秘密派对开始! 这位万能生成器让人头疼的问题终于迎刃而解——GPT能为你吹气成猴!它帮你创作角色如同魔法一般。 首先,…

【玩转Docker小鲸鱼叭】虚拟化技术简介

什么是虚拟化技术&#xff1f; Docker 是一款基于容器虚拟化技术构建的软件&#xff0c;那到底什么虚拟化技术呢&#xff1f;在学习 Docker 之前&#xff0c;先简单了解下虚拟化技术。 虚拟化是云原生的实现基础&#xff0c;它能够帮助我们更加有效地利用物理计算机硬件。 虚…