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
相关产品推荐
相关产品推荐

