当我运行我的应用程序时,它会引发很多错误,并且我的设备上的红色/黄色错误屏幕会自动刷新并显示预期的输出。
从日志中我可以看到,首先我的对象返回为 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 的正文限制)
截图:
最佳答案
async
和 await
是一种在 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/