获取异步函数的NULL值(使用await之后),然后更新为新值 [英] Getting NULL value for async function (after using await) then updating to the new value
问题描述
运行我的应用程序时,它会引发很多错误,并且设备上的红色/黄色错误屏幕会自动刷新并向我显示预期的输出.
从日志中,我可以看到我的对象首先返回为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中处理异步编程的机制.
异步操作让您的程序在等待时完成工作 完成另一项操作.
因此,只要某个方法被标记为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>'
这是因为,由于该方法的返回类型被标记为 希望这会有所帮助! When I run my app it throws a lot of errors, and the red/yellow error screen on my device, which refreshes automatically and shows me the expected output then. From the log I can see that first my object is return as null, which somehow later updates and I get the output. I have recently started Android Dev (Flutter) I tried to follow a number of online guides and also read related questions on async responses but no troubleshooting has been helping me.
My biggest problem being that I can't figure out what exactly is the problem. In my _AppState class: Expected output (Terminal): Actual output (Terminal): https://gist.github.com/Purukitto/99ffe63666471e2bf1705cb357c2ea32 (Actual error was crossing the body limit of StackOverflow) ScreenShots:
The Asynchronous operations let your program complete work while waiting
for another operation to finish. So whenever a method is marked as Example: Incorrectly using an asynchronous function The following example shows the wrong way to use an asynchronous function If you run the above program it will produce the below output - This is because, since the return type of the method is marked as Future, the program will treat is as an asynchronous method. To get the user’s order, Async and await The async and await keywords provide a declarative way to define asynchronous functions and use their results. So whenever you declare a function to be Case in point In your case, the But here So the program does not wait for completion of the Hence the red and yellow screen error. Solution The solution to this problem is you can show a loading indicator on the screen until the data is loaded completely. You can use a Example - Hope this helps! 这篇关于获取异步函数的NULL值(使用await之后),然后更新为新值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! 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
async
and await
is a mechanism for handling Asynchronous programming in Dart.
async
, your program does not pause for completion of the method and just assumes that it will complete at some point in the future.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>'
createOrderMessage()
should call getUserOrder()
and wait for it to finish. Because createOrderMessage()
does not wait for getUserOrder()
to finish, createOrderMessage()
fails to get the string value that getUserOrder()
eventually provides.
async
, you can use the keyword await
before any method call which will force the program to not proceed further until the method has completed.
fetchData()
function is marked as async
and you are using await
to wait for the network calls to complete.fetchData()
has a return type of Future<void>
and hence when you call the method inside initState()
you have to do so without using async/ await
since initState()
cannot be marked async
.fetchData()
method as a whole and tries to display data which is essentially null
.
And since you call setState()
after the data is loaded inside fetchData()
, the screen refreshes and you can see the details after some time.
bool
variable and change the UI depending the value of that variable.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
);
}
}