如何等待异步函数结束?
How to wait for async function to end?
我有一个小部件 class 可以从后端加载用户消息并将其显示在屏幕上。我在小部件 class 构建函数中调用我的异步函数 getConversations
来获取用户的消息。但我不知道如何等待该功能结束。它在我的构建函数 returns 空列表之后结束。这是我的代码:
获取对话:
Future<List<Conversation>> getConversations(BuildContext context) async {
Map<String,dynamic> conversations;
try{
var getMessagesUrl=Uri.http(BackendBaseURL,'/user/messages/');
print('before post');
var response = await http.post(getMessagesUrl,body:convert.jsonEncode({'id':_userID}));
print('after post');
if(response.statusCode==200){
conversations=convert.jsonDecode(response.body) as Map<String,dynamic>;
print(conversations);
return conversations.entries.map(
(conversation) => Conversation(
conversation.key,
conversation.value.map(
(message) => Message(message['message'],message['sent_by_user'],message['send_date'])
).toList().cast<Message>()
)
).toList();
}
else
showErrorDialog(context, 'Sunucuya bağlanılamadı.');
}
on Exception catch(e){
print(e);
showErrorDialog(context, 'Sunucuya bağlanılamadı.');
}
return [];
}
构建函数:
@override
Widget build(BuildContext context){
List<Conversation> conversations=[];
getConversations(context).then((value) => conversations=value);
print('then: '+conversations.toString());
//Need to wait getConversations function here before continuing
return Scaffold(
appBar: AppBar(
title: Text(this._username),
),
body:Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
]..addAll(conversations),
),
);
}
我的输出是这样的:
I/flutter ( 3034): before post
I/flutter ( 3034): then:[]
I/flutter ( 3034): after post
I/flutter ( 3034): {belkanahmet: [{message: ii sn, sent_by_user: true, send_date: 2021-07-02T15:32:54+03:00}, {message: nbr, sent_by_user: false, send_date: 2021-06-26T21:44:58+03:00}]}
您可以使用 Stream Builder Widget。这允许您使用 Connection.state 函数来了解您的流处于哪种状态。然后您可以 运行 只有在连接状态完成等待时才可以使用您的方法
FutureBuilder class 是我一直在寻找的(感谢@quoci)
使用 FutureBuilder,我能够 return 不同的小部件用于不同的数据值。在我的例子中,在我得到 API 的响应后,我能够 return 与我的构建函数不同的主体。这是工作代码:
获取对话:
@override
Widget build(BuildContext context){
List<Conversation> conversations=[];
getConversations(context).then((value) => conversations=value);
return Scaffold(
appBar: AppBar(
title: Text(this._username),
),
body:FutureBuilder(
future: getConversations(context),
initialData: [],
builder: (builder,snapshot){
if(snapshot.connectionState==ConnectionState.waiting) //While waiting for response return this
return Center(
child:CircularProgressIndicator()
);
return Column( //After getting response return this
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
]..addAll(conversations),
);
},
),
);
}
我有一个小部件 class 可以从后端加载用户消息并将其显示在屏幕上。我在小部件 class 构建函数中调用我的异步函数 getConversations
来获取用户的消息。但我不知道如何等待该功能结束。它在我的构建函数 returns 空列表之后结束。这是我的代码:
获取对话:
Future<List<Conversation>> getConversations(BuildContext context) async {
Map<String,dynamic> conversations;
try{
var getMessagesUrl=Uri.http(BackendBaseURL,'/user/messages/');
print('before post');
var response = await http.post(getMessagesUrl,body:convert.jsonEncode({'id':_userID}));
print('after post');
if(response.statusCode==200){
conversations=convert.jsonDecode(response.body) as Map<String,dynamic>;
print(conversations);
return conversations.entries.map(
(conversation) => Conversation(
conversation.key,
conversation.value.map(
(message) => Message(message['message'],message['sent_by_user'],message['send_date'])
).toList().cast<Message>()
)
).toList();
}
else
showErrorDialog(context, 'Sunucuya bağlanılamadı.');
}
on Exception catch(e){
print(e);
showErrorDialog(context, 'Sunucuya bağlanılamadı.');
}
return [];
}
构建函数:
@override
Widget build(BuildContext context){
List<Conversation> conversations=[];
getConversations(context).then((value) => conversations=value);
print('then: '+conversations.toString());
//Need to wait getConversations function here before continuing
return Scaffold(
appBar: AppBar(
title: Text(this._username),
),
body:Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
]..addAll(conversations),
),
);
}
我的输出是这样的:
I/flutter ( 3034): before post
I/flutter ( 3034): then:[]
I/flutter ( 3034): after post
I/flutter ( 3034): {belkanahmet: [{message: ii sn, sent_by_user: true, send_date: 2021-07-02T15:32:54+03:00}, {message: nbr, sent_by_user: false, send_date: 2021-06-26T21:44:58+03:00}]}
您可以使用 Stream Builder Widget。这允许您使用 Connection.state 函数来了解您的流处于哪种状态。然后您可以 运行 只有在连接状态完成等待时才可以使用您的方法
FutureBuilder class 是我一直在寻找的(感谢@quoci)
使用 FutureBuilder,我能够 return 不同的小部件用于不同的数据值。在我的例子中,在我得到 API 的响应后,我能够 return 与我的构建函数不同的主体。这是工作代码:
获取对话:
@override
Widget build(BuildContext context){
List<Conversation> conversations=[];
getConversations(context).then((value) => conversations=value);
return Scaffold(
appBar: AppBar(
title: Text(this._username),
),
body:FutureBuilder(
future: getConversations(context),
initialData: [],
builder: (builder,snapshot){
if(snapshot.connectionState==ConnectionState.waiting) //While waiting for response return this
return Center(
child:CircularProgressIndicator()
);
return Column( //After getting response return this
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
]..addAll(conversations),
);
},
),
);
}