gpt4 book ai didi

android - 获取异步函数的 NULL 值(在使用 await 之后)然后更新为新值

转载 作者:行者123 更新时间:2023-12-03 02:44:59 25 4
gpt4 key购买 nike

当我运行我的应用程序时,它会引发很多错误,并且我的设备上的红色/黄色错误屏幕会自动刷新并显示预期的输出。

从日志中我可以看到,首先我的对象返回为 null,稍后以某种方式更新,我得到了输出。

我最近开始了 Android Dev (Flutter)

我尝试遵循许多在线指南并阅读有关异步响应的相关问题,但没有任何故障排除对我有帮助。
我最大的问题是我无法弄清楚到底是什么问题。

在我的 _AppState 类中:

  void initState() {
super.initState();
fetchData();
}

fetchData() async {
var cityUrl = "http://ip-api.com/json/";
var cityRes = await http.get(cityUrl);
var cityDecodedJson = jsonDecode(cityRes.body);
weatherCity = WeatherCity.fromJson(cityDecodedJson);
print(weatherCity.city);
var weatherUrl = "https://api.openweathermap.org/data/2.5/weather?q=" +
weatherCity.city +
"," +
weatherCity.countryCode +
"&appid=" +
//Calling open weather map's API key from apikey.dart
weatherKey;
var res = await http.get(weatherUrl);
var decodedJson = jsonDecode(res.body);
weatherData = WeatherData.fromJson(decodedJson);
print(weatherData.weather[0].main);
setState(() {});
}

预期输出(终端):
Mumbai
Rain

实际输出(终端): https://gist.github.com/Purukitto/99ffe63666471e2bf1705cb357c2ea32 (实际错误超出了 StackOverflow 的正文限制)

截图:
At run initial
After a few seconds

最佳答案

asyncawait是一种在 Dart 中处理异步编程的机制。

Asynchronous operations let your program complete work while waiting for another operation to finish.



所以每当一个方法被标记为 async ,你的程序不会因为方法的完成而暂停,只是假设它会在将来的某个时间完成。

示例:错误使用异步函数

以下示例显示了使用异步函数的错误方法 getUserOrder() .
String createOrderMessage () {
var order = getUserOrder();
return 'Your order is: $order';
}

Future<String> getUserOrder() {
// Imagine that this function is more complex and slow
return Future.delayed(Duration(seconds: 4), () => 'Large Latte');
}

main () {
print(createOrderMessage());
}

如果您运行上述程序,它将产生以下输出 -
Your order is: Instance of '_Future<String>'

这是因为,由于方法的返回类型被标记为 Future ,程序会将is视为异步方法。

获取用户订单, createOrderMessage()应调用 getUserOrder()并等待它完成。因为 createOrderMessage()不等待 getUserOrder()完成, createOrderMessage()获取不到 getUserOrder() 的字符串值最终提供。

异步和等待

async 和 await 关键字提供了一种声明方式来定义异步函数并使用它们的结果。

因此,每当您将函数声明为 async ,您可以使用关键字 await在任何方法调用之前,这将强制程序在方法完成之前不继续进行。

例子

在您的情况下, fetchData()函数标记为 async而您正在使用 await等待网络调用完成。

但是这里 fetchData()返回类型为 Future<void>因此,当您调用 initState() 中的方法时你必须这样做而不使用 async/ await自从 initState()无法标记 async .

所以程序不会等待 fetchData() 的完成。方法作为一个整体,并尝试显示本质上是 null 的数据.
既然你调用 setState()fetchData() 内部加载数据后,屏幕刷新,一段时间后您可以看到详细信息。

因此出现红色和黄色屏幕错误。

解决方案

此问题的解决方案是您可以在屏幕上显示加载指示器,直到数据完全加载。

您可以使用 bool变量并根据该变量的值更改 UI。

示例 -
class _MyHomePageState extends State<MyHomePage> {
bool isLoading = false;

void initState() {
super.initState();
fetchData();
}

fetchData() async {
setState(() {
isLoading = true; //Data is loading
});
var cityUrl = "http://ip-api.com/json/";
var cityRes = await http.get(cityUrl);
var cityDecodedJson = jsonDecode(cityRes.body);
weatherCity = WeatherCity.fromJson(cityDecodedJson);
print(weatherCity.city);
var weatherUrl = "https://api.openweathermap.org/data/2.5/weather?q=" + weatherCity.city + "," +
weatherCity.countryCode +
"&appid=" +
//Calling open weather map's API key from apikey.dart
weatherKey;
var res = await http.get(weatherUrl);
var decodedJson = jsonDecode(res.body);
weatherData = WeatherData.fromJson(decodedJson);
print(weatherData.weather[0].main);
setState(() {
isLoading = false; //Data has loaded
});
}

@override
Widget build(BuildContext context) {
return Scaffold(
body: isLoading ? Center(child : CircularProgressIndicator())
: Container(), //Replace this line with your actual UI code
);
}
}

希望这可以帮助!

关于android - 获取异步函数的 NULL 值(在使用 await 之后)然后更新为新值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57551482/

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