繁体   English   中英

当我运行我的代码时,它会给出错误代码 400,但是当我进行热刷新时,它会在控制台中显示数据,同时从 flutter 中的 api 获取数据

[英]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时,只需再次执行buildgetData ,因此代码可以正常工作。

解决此问题的最简单方法是将对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);
      }
    }

还值得一提的是getDatagetLocation的返回类型都是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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM