![](/img/trans.png)
[英]when I've tried to run my flutter in vs code it gave this error in debug console
[英]when i run my code it gives error code 400 but when i do hot refresh it shows data in console while getting data from api in flutter
当我运行我的代码时,它会给出错误代码 400,但是当我进行热刷新时,它会在控制台中显示数据,同时从 flutter 中的 api 获取数据
这意味着 API 需要时间来发送数据但我的代码没有等待我也在使用异步等待但仍然
如果可以的话请帮忙
我在这里尝试获取数据
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:weather_app/services/location.dart';
import 'package:weather_app/utilities/constants.dart';
class LoadingScreen extends StatefulWidget {
@override
_LoadingScreenState createState() => _LoadingScreenState();
}
class _LoadingScreenState extends State<LoadingScreen> {
double latitude;
double longitude;
@override
void initState() {
super.initState();
getLocation();
}
void getLocation() async {
GettingLocation gettingLocation = GettingLocation();
await gettingLocation.getCurrentPosition();
lattitude = gettingLocation.latitude;
longitude = gettingLocation.longitude;
}
void getData() async {
http.Response response = await http.get(Uri.parse(
'https://api.openweathermap.org/data/2.5/weather?lat=$lattitude&lon=$longitude&appid=$apiKey'));
if (response.statusCode == 200) {
String data = response.body;
print(data);
} else {
print(response.statusCode);
}
}
@override
Widget build(BuildContext context) {
getData();
return Scaffold();
}
}
这是位置。dart
import 'package:geolocator/geolocator.dart';
class GettingLocation {
double latitude;
double longitude;
Future<void> getCurrentPosition() async {
try {
Position position = await Geolocator.getCurrentPosition(
desiredAccuracy: LocationAccuracy.low);
latitude = position.latitude;
longitude = position.longitude;
} catch (e) {
print(e);
}
}
}
问题不在于 API 需要时间返回数据,问题在于异步方法执行的顺序。
这是您显示的执行顺序:
initState -> build -> getData -> getLocation
因此,当 getData 执行时,getLocation 尚未执行完毕,因此纬度和经度没有正确的值。 当您运行hot reload
时,只需再次执行build
和getData
,因此代码可以正常工作。
解决此问题的最简单方法是将对getLocation
的调用直接移动到getData
中,但这意味着获取数据需要更长的时间,因为getPosition
只会在您执行getData
时开始执行。
首先,从initState
中删除getPosition
,然后在getData
上
void getData() async {
await getLocation(); // <------ this line
http.Response response = await http.get(Uri.parse(
'https://api.openweathermap.org/data/2.5/weather?lat=$lattitude&lon=$longitude&appid=$apiKey'));
if (response.statusCode == 200) {
String data = response.body;
print(data);
} else {
print(response.statusCode);
}
}
还值得一提的是getData
和getLocation
的返回类型都是void
,这在处理异步回调时可能会产生意想不到的后果,我建议您将其替换为Future<void>
Future<void> getLocation() { ... }
Future<void> getData() { ... }
最后,正如我所说,这个解决方案有一点缺点,就是稍后会调用getLocation
,实际上这应该没有任何问题,因为时间差异应该很小,但我仍然使用FutureBuilder
做了一个例子这将显示getData
数据:
class LoadingScreen extends StatefulWidget {
@override
_LoadingScreenState createState() => _LoadingScreenState();
}
class _LoadingScreenState extends State<LoadingScreen> {
double latitude;
double longitude;
late Future<void> _locationFuture;
@override
void initState() {
super.initState();
_locationFuture = getLocation();
}
Future<void> getLocation() async {
GettingLocation gettingLocation = GettingLocation();
await gettingLocation.getCurrentPosition();
lattitude = gettingLocation.latitude;
longitude = gettingLocation.longitude;
}
Future<String?> getData() async {
await _locationFuture;
http.Response response = await http.get(Uri.parse(
'https://api.openweathermap.org/data/2.5/weather?lat=$lattitude&lon=$longitude&appid=$apiKey'));
if (response.statusCode == 200) {
return response.body;
print(data);
} else {
print(response.statusCode);
}
}
@override
Widget build(BuildContext context) {
return FutureBuilder<String?>(
future: getData(),
builder: (context, snapshot) {
if (snapshot.hasData) return Text(snapshot.data!);
return CircularProgressIndicator();
}
);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.