虚中有实——try catch 的异步捕获

try-catch 原理

try-catch 是一种异常处理机制,用于捕获和处理代码中可能抛出的异常。

  • 当程序执行到 try 块时,会按照顺序执行其中的代码;
  • 如果 try 块中的代码执行异常,程序会立即跳转到与 catch 关键字对应的 catch 块中执行;
  • 在 catch 块中,可以对异常进行捕获和处理,比如打印错误信息、记录日志、或者进行一些恢复性操作;
  • 如果 catch 块中的代码执行完毕,程序会继续执行 try-catch 块之后的代码;

Future 原理

Future 是 Dart 中用于处理异步操作的关键字之一。当调用一个异步函数时,该函数会立即返回一个 Future 对象,表示异步操作的结果,异步对象可能是一个值,也可能是一个异常。Future 的主要使用场景包括:

  1. 异步操作的结果表示:当需要执行一个耗时的操作,例如从网络获取数据、文件读写操作等,而不想阻塞当前线程时,就可以使用 Future 来表示这个异步操作的结果。通过 Future,我们可以在异步操作完成后获取到操作的结果,或者在操作失败时获取到错误信息。
  2. 异步操作的串行化和并行化:通过 Future,我们可以将多个异步操作串行化或并行化执行,从而提高程序的性能和响应速度。例如,使用 Future.then() 方法可以在一个异步操作完成后执行另一个异步操作,或者使用 Future.wait() 方法可以等待多个异步操作全部完成后再进行下一步操作。
  3. 异常处理:Future 也提供了异常处理的功能。当一个异步操作失败时,可以通过 catchError() 方法或 try-catch 块来捕获异常,并进行相应的处理。

Future 的原理主要是基于事件循环和回调机制。当一个异步操作被调用时,它会立即返回一个 Future 对象,表示该操作的结果。然后,异步操作会在后台执行,而不会阻塞当前线程。当操作完成时,会通知事件循环,并将操作的结果传递给对应的 Future 对象。这时,可以通过 Future 对象的方法来获取操作的结果或处理可能发生的异常。

总的来说,Future 关键字提供了一种便捷的方式来处理异步操作,使得程序可以更加高效地利用资源,并提高用户体验。

例子分析

void main() async {
    Future<dynamic> catchMethodA(Function executionMethod) async {
      return await executionMethod();
    }

    Future<dynamic> catchMethodB() async {
      print("catchMethodB executioned");
      throw Exception("catchMethodB throw Error");
    }

    try {
      var methodAResult = await catchMethodA(() {
        try {
          return catchMethodB();
        } catch (e) {
          print("catch a exception in catchMethodB");
        }
      });
      print("methodAResult=$methodAResult");
    } on Exception {
      print("catch a Exception in catchMethodA, it's main method");
    } on Error {
      print("catch a Error in catchMethodA, it's main method");
    }

}


提问:1、执行结果应该是什么2、为什么

print:

catchMethodB executioned
catch a exception in catchMethodA, it's main method

为什么:

内部函数catchMethodB执行前没有使用 await 进行同步处理,并不会等待异步操作完成,执行它将会立即返回一个 Future<dynamic> 对象。在这种情况下,第一次捕获的将是一个 Future<dynamic> 对象,而不是实际的异常。

这意味着外部 methodAResult 捕获的是一个未完成的 Future 对象,其结果值为异常。外部的 try-catch 块通过 await 关键字等待这个 Future 对象的完成,当异步操作完成后,该 Future 对象的状态将变为已完成,并且携带着异常的信息。捕获到了其中携带的异常信息。

让我们逐步分析这段代码的执行过程:

  1. main 函数开始执行。
  2. catchMethodA 函数被调用,传入一个匿名函数作为参数。
  3. catchMethodA 函数内部执行传入的匿名函数,即执行以下代码:
  4. 在匿名函数内部,catchMethodB 函数被调用。
  5. catchMethodB 函数内部执行,并打印一条信息。
  6. catchMethodB 函数抛出一个异常 Exception("catchMethodB Error")
  7. Exception("catchMethodB Error")Future<dynamic> 对象返回给methodAResult
  8. catchMethodA 函数接收到异常的 Future 对象,并立即返回给 main 函数。
  9. main 函数中的 try-catch 块捕获到异常的 Future 对象,并执行 catch 块中的代码,打印一条信息 "catch a exception in catchMethodA, it's main method"

因此,main 函数的执行结果是打印如下信息:

catchMethodB executioned
catch a exception in catchMethodA, it's main method

在给定的代码中,"catch a exception in catchMethodB" 没有被打印出来,这是因为异常并没有在 catchMethodB 函数内部被捕获。让我们仔细分析一下原因:

  1. catchMethodB 函数内部没有显式的 try-catch 块来捕获可能抛出的异常;
  2. 异常在 catchMethodB 函数内部抛出后, 以 Future<dynamic>返回会沿着调用栈向上层传播,直到找到一个可以捕获异常的 try-catch 块或直到程序终止;

因此,即使异常是在 catchMethodB 函数内部抛出,但实际上异常的处理是 main 进行的,所以 "catch a exception in catchMethodB" 没有被打印出来。

catch 的捕获项

或许到这里就结束了,但是还想进一步梳理下 catch 的捕获信息

常见异常的继承关系:

Exception
├─ ArgumentError
├─ FormatException
├─ RangeError
├─ StateError
└─ TypeError
Error
├─ AssertionError
├─ CastError
├─ ConcurrentModificationError
├─ FileSystemException
├─ HttpException
├─ NoSuchMethodError
├─ SocketException
└─ TimeoutException

Exception 与 Error

ExceptionError 都是用于表示程序中出现的问题的类,但它们在设计初衷和使用场景上存在一些差异:

  1. Exception(异常):设计初衷:Exception 类用于表示程序中的一般性错误或非预期情况。它通常表示由程序错误、无效参数、无效状态等引起的异常情况。使用场景:通常情况下,我们会在代码中显式地抛出 Exception 类或其子类的实例,来表示程序中的异常情况。在捕获异常时,我们可以选择捕获特定类型的 Exception 或捕获所有类型的异常(使用 catch (Exception e) 或 catch (e))。
  2. Error(错误):设计初衷:Error 类用于表示程序中的错误情况,通常表示更严重的问题,如内存不足、堆栈溢出等。与 Exception 不同,Error 表示的是由于程序错误或系统错误导致的问题,而不是程序中的一般性异常情况。使用场景:通常情况下,Error 不应该被捕获和处理,而是应该由开发者解决并修复问题。如果程序中出现 Error,通常意味着存在严重的问题,可能会导致程序崩溃或无法继续运行。因此,我们不建议捕获 Error,而是应该尽量避免出现这些错误,或者在出现 Error 时及时停止程序并报告问题。

总的来说,ExceptionError 在设计初衷和使用场景上有所区别:Exception 主要用于表示程序中的一般性异常情况,而 Error 则表示更严重的问题,通常需要开发者进行处理和解决。在实际开发中,我们应该根据具体情况选择合适的异常类型,并采取适当的措施来处理和修复问题,以提高程序的健壮性和可靠性。

常的异常类型的使用场景:

Exception

通用异常类型,表示程序中的一般性错误

处理非预期的程序错误、无效参数等

ArgumentError

表示由于参数不正确而引发的异常

处理函数接收到无效参数的情况

RangeError

表示由于超出有效范围而引发的异常

处理超出范围的索引或值

FormatException

表示由于格式不正确而引发的异常

处理用户输入或解析数据时的格式化错误

StateError

表示由于对象状态不正确而引发的异常

处理对象处于不允许的状态时执行操作的情况

TypeError

表示由于对象类型不匹配而引发的异常

处理对象转换或操作类型不匹配的情况

CastError

表示由于强制类型转换失败而引发的异常

处理类型转换失败的情况

NoSuchMethodError

表示由于调用不存在的方法而引发的异常

处理调用对象不存在的方法的情况

UnsupportedError

表示由于调用不支持的操作而引发的异常

处理调用对象不支持的操作的情况

ConcurrentModificationError

表示由于并发修改集合而引发的异常

处理在迭代期间修改了集合的情况

StateError

表示由于对象状态不正确而引发的异常

处理对象处于不允许的状态时执行操作的情况

AssertionError

表示由于断言失败而引发的异常

处理条件不满足时触发的断言失败的情况

FileSystemException

表示由于文件系统操作失败而引发的异常

处理文件读写、目录操作等操作失败的情况

HttpException

表示由于 HTTP 请求失败而引发的异常

处理 HTTP 请求失败的情况

TimeoutException

表示由于操作超时而引发的异常

处理操作超时的情况

SocketException

表示由于套接字操作失败而引发的异常

处理套接字操作失败的情况

...

其他自定义异常类型

处理特定领域的异常情况

天龙八部——内功篇 文章被收录于专栏

日常工作遇到的基础积累

全部评论

相关推荐

2024-12-16 10:44
北京邮电大学 Java
之前说过如果拿到美团offer就把这么多轮的面试经验全写出来先说一下本人的经历有9个部门约面,2次拒面,4次二面挂,1次hr面挂,2次一面挂9月初做完笔试,隔了一周,优选约面了,秋招第一面,面的很差,没有准备好,手撕sql没写出来,另一道手撕写的不太好,果不其然一面挂9.30金服约面,这次面试全是八股,此时我的八股水平相当一般,每次深挖都不会,手撕是合并两个升序链表,一面寄过完国庆回来半个月美团再没约面过了知道10.20左右,SaaS部门约面这下就开启了我的噩梦循环,一面面评很不错,二面面试官问了在滴滴实习的限流的底层原理,实习的时候就没太看懂,面试的时候答的不好,但是侥幸二面过了,hr面的时候面试官问对大厂的印象,直接胡说八道了,过了三天人才库月底又面一轮到家二面问了很多场景题,答的都不太好,面试官提醒才能理清思路,面完就挂了走完这一轮面试已经11月了,11月更是噩梦循环,3次二面挂,可能因为之前有终面挂的经历面评还不错首先是美团平台,这个印象不深,自我感觉答的还可以,面试官也聊的不错,最后挂了,给面试官发邮件问了,面试官说前面的人接了offer,没有hc了遂挂然后就是我最想去的部门和base,成都的到家做营销业务的,面试很顺利,二面面试官是我的老乡,面完又开始紧张等待结果,还是挂了最后是核心本地平台做对内的系统的,可能还不如手里的保底offer,最后也不太想去,但是还是面了,二面挂,想不通时间到了12月,我的心态也是出奇的好,这个时候又陆陆续续有两个部门约面,但是心态已经很疲惫了,加上业务也不好,直接拒面了,每次来来回回都是半个月,很耽误时间,上周目前这个部门约面,一开始说周五面试,后面面试官有事又改到这周一,最后因为主管要出差,直接约面的第二天就面试了,两轮面完,第二天就oc了,谈薪没a动,但是也收到了正式offer,感觉也还能接受,剩下等等阿里和邮储就差不多签了一些面试tips1.这几次面试挂都是3天人才库,我看网上有的是长时间没有操作回的,可以问问面试官,有时候会捞回去2.美团面试是我秋招面试里最爱问八股的,一定要好好准备,问的也不难3.美团大部分技术面都有手撕,有时候会让写sql,没准备过,遇到一次寄4.很神奇每次面试碰到问最近看什么书这个问题的都挂了,感觉问这种问题就是面试官已经对你不感兴趣但是还要凑时长5.面试一定要好好准备,面了13次面试每次都有新的不会的点,一面八股居多,也看面试官,场景题最好也准备准备,普通八股是基础,一些中间件的原理也得知道6.坚持一定有好结果
甜美的牛牛在写bug:下载美团外卖没绷住
点赞 评论 收藏
分享
MScoding:第一次见放闲鱼界面的
点赞 评论 收藏
分享
评论
1
1
分享

创作者周榜

更多
牛客网
牛客企业服务