gpt4 book ai didi

dart - Future catchError 函数在未立即链接时不会捕获错误

转载 作者:行者123 更新时间:2023-12-02 18:22:16 32 4
gpt4 key购买 nike

考虑这段代码:
示例 A:

Future<void> fakeCall() async {
await Future.delayed(const Duration(milliseconds: 300), () {
throw MyError('myException');
});
}

Future<void> fetch() async {
Future<void> testFuture = fakeCall();

testFuture.whenComplete(() {
print('when completed');
});
testFuture.catchError((e) {
print('on error');
});
return testFuture;
}

void main() async {
try{
await fetch();
}on MyError catch(e){
//getting here but one still leaks!!
}
}

当调用await fetch()时,我希望只调用catchError。但错误以某种方式泄漏,所以基本上抛出了两个...一个被 catchError 捕获,一个作为未处理的错误泄漏到外部。

但是当按照建议的方式使用它时(一个接一个地链接):
示例 B:

Future<void> fakeCall() async {
await Future.delayed(const Duration(milliseconds: 300), () {
throw MyError('myException');
});
}

Future<void> fetch() async {
Future<void> testFuture = fakeCall().whenComplete(() {
print('when completed');
}).catchError((e) {
print('on error');
});

return testFuture;
}

void main() async {
try{
await fetch();
}on MyError catch(e){
//getting here and nothing leaks!!
}
}

没有发生错误泄漏。这让我非常好奇有人可以解释为什么用第一种方式编写它会导致错误泄漏吗?


更新

最初我忘记在 fetch 函数周围添加 try/catch,所以您可能认为错误是因为这个原因泄漏的。但请注意,当未正确链接 onError 时,错误仍然会泄漏(第一个示例)

最佳答案

错误被泄露,因为您正在等待 Future 的结果,最终完成时出现错误:

await fetch();

重要的是要理解,Future 对象只是一个值,它有时会在将来获取一个值,并且该值可以是一个值,也可以是一个错误。

catchError() 是一种订阅在 Future 作为错误完成时要执行的代码的方法。该方法返回一个新的 future,其逻辑是在原始 future 完成且没有任何错误的情况下获取原始值。但是,如果源完成时出现错误,catchError() 会运行指定的方法并在执行后返回值。

catchError() 不会更改有关 Future 的任何内容,因此您可以根据需要多次调用 catchError()

我应该补充一点,我认为最好在异步标记函数中使用传统的 try...catch(与 await 组合),而不是使用 catchError() code> 因为它使代码更具可读性且不易混淆:

Future<void> fetch() async {
try {
await fakeCall();
} catch (e) {
print('on error');
} finally {
print('when completed');
}
}

void main() async {
await fetch();
}

输出:

on error
when completed

问题更改后更新

“示例 B”的问题在于您假设 whenComplete() 确实处理任何错误。但如果您阅读文档:

The future returned by this call, f, will complete the same way as this future unless an error occurs in the action call, or in a Future returned by the action call. If the call to action does not return a future, its return value is ignored.

https://api.dart.dev/stable/2.15.1/dart-async/Future/whenComplete.html

因此返回的 Future 没有改变其行为,因此如果源 Future 完成时出现错误,Future 也会发生同样的情况从 whenComplete() 创建。由于您没有在此 Future 上附加任何错误处理,因此您的程序会失败。

关于dart - Future catchError 函数在未立即链接时不会捕获错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70730975/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com