我遇到了一个我无法解决的行为。基本上,我试图获取数据,并返回这些数据的Future
,其中一些请求可能会失败,但我们可以忽略它们。
这是我到目前为止的想法:对于我们想要获取的每个数据,创建一个future,如果失败则返回null,否则返回值。然后等待所有future,并删除null值。
下面是我的代码:(简单测试数据)
Future<List<String>> testFunc() {
// create a result list
List<Future<String?>> result = List.empty(growable: true);
// put 10 future in the results
for(int i = 0; i < 10; i++) {
result.add(
// create a future that may fail
Future.delayed(Duration(seconds: i), () {
if(i % 2 == 0) { return i; }
else { throw Error(); }
})
// if the future succeed, return the value
.then((value) {
return "got from future : $value";
})
// otherwise, returns "null" as we are expecting a future returning a nullable value
.catchError((error) {
return null; // <========= Linter error here
})
);
}
// then, wait for all futures, and remove the ones that crashed
return Future.wait(result).then((listOfNullable) => listOfNullable.where((element) => element != null).map((e) => e!).toList());
}
当我运行这个函数时,其中一个future失败并返回null,我遇到了一个错误:The error handler of Future.catchError must return a value of the future's type
,我不明白,因为null是String?
的有效值?
有一种方法是显式强制转换:
Future<List<String>> testFunc() {
// create a result list
List<Future<String?>> result = List.empty(growable: true);
// put 10 future in the results
for(int i = 0; i < 10; i++) {
result.add(
// create a future that may fail
Future.delayed(Duration(seconds: i), () {
if(i % 2 == 0) { return i; }
else { throw Error(); }
})
// if the future succeed, return the value
.then((value) {
return "got from future : $value" as String?; // <========= Linter error here
})
// otherwise, returns "null" as we are expecting a future returning a nullable value
.catchError((error) {
return null as String?; // <========= Linter error here
})
);
}
// then, wait for all futures, and remove the ones that crashed
return Future.wait(result).then((listOfNullable) => listOfNullable.where((element) => element != null).map((e) => e!).toList());
}
但是现在,linter告诉我我有一个不必要的造型,我正在尝试删除任何linter错误。
我错过了什么?
2条答案
按热度按时间hi3rlvi21#
linter错误是由对
then(...)
的调用引起的,dart linter急切地将其解析为then<String>
而不是then<String?>
。您可以显式指定类型以解决此行为:
bq9c1y662#
也就是说,提供给
Future<T>.catchError
的回调必须返回T
或Future<T>
(也称为FutureOr<T>
)。由于您在
Future.then<R>
返回的Future<R>
上调用catchError
,因此错误回调必须返回FutureOr<R>
。您需要:由于没有为
Future.then<R>
提供显式类型,R
是从callback的返回类型(不可为空的String
. As jraufeisen explained)中推断出来的,因此可以通过显式指定R
(而不是允许它被推断出来)来修复此问题。或者,我强烈建议使用
async
-await
和try
-catch
,而不是使用Future.then
和Future.catchError
。这样做可以避免这些问题(或者至少使它们更容易推理)。在您的情况下,helper函数会使转换更容易:使用
.map
代替.where
来过滤掉null
s,使用collection-for
来避免创建一个空的List
并使其增长,并删除剩余的Future.then
: