Future.then 必须返回返回的 future 类型的值



我不断收到这个错误

Unhandled Exception: Invalid argument(s) (onError): The error handler of Future.then must return a value of the returned future's type

NetworkApi

class NetworkApi {
NetworkApi(this.url);
final String url;
Future getData() async {
http.Response response = await http.get(Uri.parse(url));
if (response.statusCode == 200) {
String data = response.body;
return jsonDecode(data);
} else {
if (kDebugMode) {
print(response.statusCode);
}
}
}
}

ApiSelector

class ApiSelector {
Future getApiData({String categoryName = ""}) async {
late NetworkApi _api;
if(categoryName != ""){
_api = NetworkApi('api');
}else{
_api = NetworkApi('myapi');
}
var Data = await _api.getData();
if (Data['status'] == 'error') {
throw'Error while fetching data';
}
return MyModel.fromJson(Data);
}
}

MyFunction调用API选择器

Future getDataFromApi() async {
await _apiSelector
.getApiData(categoryName: "Some Category")
.then((value) {
myModel = value as MyModel;
print(myModel);
return value;
} ,onError: (error) {
print(error);
return error;
},);
}

我想尽一切办法来解决这个问题。请你指导我该怎么做。我甚至尝试过异常处理,但仍然出现了这个错误。

指定返回类型的Future,如Future<dynamic>

NetworkApi

class NetworkApi {
NetworkApi(this.url);
final String url;
Future<dynamic> getData() async {
http.Response response = await http.get(Uri.parse(url));
if (response.statusCode == 200) {
String data = response.body;
return jsonDecode(data);
} else {
if (kDebugMode) {
print(response.statusCode);
}
}
}
}

ApiSelector

class ApiSelector {
Future<MyModel> getApiData({String categoryName = ""}) async {
late NetworkApi _api;
if(categoryName != ""){
_api = NetworkApi('api');
}else{
_api = NetworkApi('myapi');
}
var Data = await _api.getData();
if (Data['status'] == 'error') {
throw'Error while fetching data';
}
return MyModel.fromJson(Data);
}
}

MyFunction调用API选择器

Future<MyModel?> getDataFromApi() async {
try {
var value = await _apiSelector.getApiData(categoryName: "Some Category");
myModel = value as MyModel;
return myModel;
} catch(error) {
print(error);
return error;
}
}

问题出现在getDataFromApi:中

Future getDataFromApi() async {
await _apiSelector
.getApiData(categoryName: "Some Category")
.then((value) {
myModel = value as MyModel;
print(myModel);
return value;
} ,onError: (error) {
print(error);
return error;
},);
}

正如错误消息所解释的,onError处理程序无法返回与Future.then的成功路径返回的类型相同的类型。(请参见https://stackoverflow.com/a/66397222/以获得解释。(这通常是一个编译时错误,但最终是一个运行时错误,因为getDataFromApi被声明为返回Future(相当于Future<dynamic>而不是Future<MyModel>

使用带有错误回调的原始FutureAPI(无论是使用Future.thenonError参数还是使用Future.catchError(直接使用都相当令人困惑。您已经在使用await,因此没有理由使用Future.then。使用await,您可以使用try-catch,这使问题更加清晰:

Future<MyModel> getDataFromApi() async {
try {  
var myModel = await _apiSelector.getApiData(categoryName: "Some Category");
print(myModel);
return myModel;
} catch (error) {
print(error);
return error; // WRONG: This is not a `MyModel`!
}
}

要解决此问题,catch块需要返回MyModel,或者必须抛出异常。

class ApiSelector {
Future getApiData({String categoryName = ""}) async {
late NetworkApi _api;
if(categoryName != ""){
_api = NetworkApi('api');
}else{
_api = NetworkApi('myapi');
}
var Data = await _api.getData();
if (Data['status'] == 'error') {
//I had to replace throw with Future.value Now All Errors are gone.
return Future.value( 'Error while fetching data');
}
return MyModel.fromJson(Data);
}
}

我希望这也能帮助其他在未来某个时候面临这种错误的人。

最新更新