You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter访问异步函数内变量 解决late延迟初始化错误

问题根源

你当前的写法有4个核心错误,导致经纬度变量始终无法正常访问:

  • 作用域覆盖:getLocation()内部用var重新声明了和外部同名的latitude、longitude局部变量,赋值操作只修改了函数内的局部变量,外部的全局变量根本没有被赋值。
  • 拼写错误:你把纬度的变量名latitude错拼成了lattitute,即使去掉var也无法正确给外部变量赋值。
  • 异步时序错误:getLocation()是异步函数,你没有等待位置获取完成就调用getData(),执行天气请求时经纬度还没被赋值。
  • 触发逻辑错误:getData()在build方法中被直接调用,页面一加载就会执行,而位置获取需要点击按钮才触发,请求天气时拿不到经纬度是必然结果。
正确实现方式

不要用全局变量传值,把状态和逻辑收敛到State类中管理,通过async/await串联异步执行顺序,等拿到位置结果后再发起天气请求。
修正后的完整代码如下:

import 'package:clima/constants.dart';
import 'package:flutter/material.dart';
import 'package:clima/services/location.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

class LoadingScreen extends StatefulWidget {
  @override
  _LoadingScreenState createState() => _LoadingScreenState();
}

class _LoadingScreenState extends State<LoadingScreen> {
  double? latitude;
  double? longitude;
  bool isLoading = false;

  Future<List<double>> getLocation() async {
    Location locs = Location();
    return await locs.getCurrentLocation();
  }

  Future<void> getData(double lat, double lon) async {
    final response = await http.get(Uri.parse(
        'https://api.openweathermap.org/data/2.5/weather?lat=$lat&lon=$lon&appid=$appId'));

    if (response.statusCode == 200) {
      final data = jsonDecode(response.body);
      final resLongitude = data['coord']['lon'];
      final description = data['weather'][0]['description'];
      print(resLongitude);
      print(description);
    } else {
      print('请求失败,状态码:${response.statusCode}');
    }
    setState(() => isLoading = false);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: isLoading
            ? const CircularProgressIndicator()
            : ElevatedButton(
                onPressed: () async {
                  setState(() => isLoading = true);
                  // 等待位置获取完成
                  final position = await getLocation();
                  latitude = position[0];
                  longitude = position[1];
                  // 拿到经纬度后再请求天气
                  await getData(latitude!, longitude!);
                },
                child: const Text('Get Location'),
              ),
      ),
    );
  }
}
注意事项
  • 函数内部的局部变量天然无法在外部直接访问,需要跨作用域传值时,优先用函数返回值、参数传递的方式实现,不要滥用全局变量,全局变量会导致代码逻辑难以追踪、容易出现时序问题。
  • 异步操作必须用await等待前序任务执行完成,再执行依赖其结果的后续操作,否则会出现访问未初始化变量的问题。
  • 不要在build方法中直接执行网络请求、位置获取这类异步操作,build会在页面状态变化时反复触发,会导致重复请求、逻辑混乱。
  • 对于无法在声明时立即赋值的变量,优先用?标记为可空类型,不要盲目加late关键字,late仅适用于你能100%保证变量在第一次被访问前一定会完成赋值的场景。

内容的提问来源于stack exchange,提问作者Suyog Gaire

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 16:42:16