簡體   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