无法与 Flutter 中异步函数中的全局变量通信



我在 Flutter 工作,在异步函数内部与程序的其余部分进行通信时遇到问题。 具体来说,我正在使用 http 请求(它必须是一个异步函数,所以这不是一个不同的选项(并尝试(在异步完成后(设置一个先前实例化的全局变量等于来自 http 请求的响应部分。

为了尝试解析这个问题,我从基本的颤振项目创建了一个最小代码示例。

要遵循的代码示例。

String username = 'xxx';
String password = 'xxx';
String basicAuth = 'Basic ' + base64Encode(utf8.encode('$username:$password'));
String url = 'xxx';
String user_phone = '5555555555';
String locationId1 = 'xxx';
String locationId2 = 'xxx';
Map info;

void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);

final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Session ID:',
),
Text(
'$sessionID',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: createSessionID,
tooltip: 'Create Session ID',
child: Icon(Icons.add),
), 
);
}
}
Future<void> createSessionID() async {
http.Response response = await http.post(
url,
headers: <String, String>{'authorization': basicAuth},
body: {'user_phone': user_phone, 'locationId1': locationId1, 'locationId2': locationId2},
);
info  = jsonDecode(response.body);
sessionID = info['session_id'];
print (info['session_id']);
return info;
}

实际上,问题是我可以将值打印到异步函数内的调试控制台,但是如果我尝试将该全局 Map 变量设置为任何内容,它始终为 null,并且从未设置。

我尝试将其设置为 Future 并返回变量,但这并没有改变它仍未正确设置的事实,因为它出于某种未知原因返回 null。

所以在上面的例子中,如果我把它改成a:

Future<Map> createTrip() async { 
<Same Code, but with 
Map data = jsonDecode(response.body);
return data;
> 
}
<void> updateInfo() async {
info = await createSessionID();
}

然后打印信息中的值,它仍然告诉我同样的事情,信息本身是空的。 因此,它永远不会从异步函数内部设置。 我只是不明白为什么。

思潮? 想法?

(编辑两次以添加原始代码,并消除混淆(

所以这里的问题是,我没有正确理解未来的概念。 (老实说,我可能仍然没有,哈哈(。

所以我认为,如果你等待响应,它会自动将变量类型的未来更改为它应该类型的变量。

那。。。 不会发生。

因此,您需要以不同的方式与程序的不同部分进行通信。 我最终使用的解决方案(可能不是最好的,但它有效,所以对我来说足够好(是使用全局变量来存储信息,然后使用 getter 将我的程序需要的局部变量设置为服务器调用用于设置的全局变量。

所以举个例子:

Map data;  // Set globally, outside the function;
Future<void> createTrip() {
// Code for server call
data = jsonDecode(response.body);
return;
}
Map getData () {
return data;
}

因此,完全避免了试图返回未来并对其进行解码的问题。 同样,这可能是非常低效的,我认为有更好的方法来做到这一点...... 但至少它有效,哈哈。

我很确定你在这里有一切正确的东西,你只是没有告诉 Flutter 更新小部件,因为你已经更新了值。

确保使用新作业呼叫setState

Future<void> createSessionID() async {
http.Response response = await http.post(
url,
headers: <String, String>{'authorization': basicAuth},
body: {'user_phone': user_phone, 'locationId1': locationId1, 'locationId2': locationId2},
);
info  = jsonDecode(response.body);
setState(() => sessionID = info['session_id']); // <--------new code
print (info['session_id']);
return info;
}

最新更新