我想获取Future
返回值,并将其用作变量。
我有这个Future
函数
Future<User> _fetchUserInfo(String id) async {
User fetchedUser;
await Firestore.instance
.collection('user')
.document(id)
.get()
.then((snapshot) {
final User user = User(snapshot);
fetchedUser = user;
});
return fetchedUser;
}
我想得到这样的价值
final user = _fetchUserInfo(id);
但是当我尝试这样使用
new Text(user.userName);
Dart无法识别为User
类。它说dynamic
。
如何获得返回值并使用它?
首先我做错了吗?
任何帮助表示赞赏!
答案 0 :(得分:10)
您可以简化代码:
Future<User> _fetchUserInfo(String id) async {
User fetchedUser;
var snapshot = await Firestore.instance
.collection('user')
.document(id)
.get();
return User(snapshot);
}
您还需要async / await来获取值
void foo() async {
final user = await _fetchUserInfo(id);
}
答案 1 :(得分:3)
要添加有关Daibaku原始问题的更多细节,这可能有助于澄清使用Flutter / dart中的Futures,user
为:
final user = _fetchUserInfo(id);
如果不让编译器推断类型,则为:
final Future<User> user = _fetchUserInfo(id);
Daibaku询问如何获取user
的返回值并使用它。
要在小部件中使用user
,您的小部件必须监视/观察更改,并在更改时自行重建。
您可以使用很多样板代码手动执行此操作,也可以使用FutureBuilder
来完成此操作:
FutureBuilder(future: user, builder: (context, snapshot)
{
if (snapshot.hasData) return Text(snapshot.data.userName);
return Container(width: 0.0, height: 0.0,);
}
更明确地说,您可以将上面的代码写为:
FutureBuilder<User>(future: user, builder: (context, AsyncSnapshot<User> userSnapshot)
{
if (userSnapshot.hasData) return Text(userSnapshot.data.userName);
return Container(width: 0.0, height: 0.0,);
}
FutureBuilder
在上面的示例中,同步(即立即)返回宽度/高度为零的Container窗口小部件,同时还将观察者附加到您的未来user
上,以了解Future数据何时到达。>
当user
最终用“数据”更新时,将通知FutureBuilder
的观察者并调用setState()
,从而开始重建自身。现在snapshot.hasData
是true
,将返回Text(snapshot.data.userName)
而不是空的Container。
如果您不是在Widget元素树构建的同步世界中使用user
,而只想打印出用于调试的值,则可以使用then
附加观察者:
user.then((u) => print(u.userName));
答案 2 :(得分:2)
var username;
dbHelper.getUsers().then((user) {
username = user.getName;
});
此函数返回未来值
dbHelper.getUsers()
它是这样写的
getUsers() async { .... }
答案 3 :(得分:2)
只是在上面的答案上添加更多的解释/描述
当一个函数返回一个 Future 时,意味着它的结果需要一段时间准备好,结果将在未来可用。
调用返回 Future 的函数不会阻塞您的代码,这就是该函数被称为异步的原因。相反,它会立即返回一个 Future 对象,该对象起初未完成。
Future<T>
表示异步操作的结果将是 T
类型。例如,如果一个函数返回 Future<String>
,这意味着将来它会为您提供一个字符串。
仅当 Future 为 completed
时,Future 的结果才可用。
您可以使用以下任一关键字访问 Future 的结果:
然后
等待
假设 getNews 函数返回 Future<String>
的一个实例。
Future<String> getNews() async {
final response = await http.get(url);
return response.body;
}
您可以通过以下任一方式使用此函数的结果:
getNews().then((news) {
print(news);
});
或
String news = await getNews();
print(news);
请注意,await 关键字只能在异步函数的主体中使用:
Future<void> foo() async {
String news = await getNews();
print(news);
}
async
函数的结果必须是 Future
。
信用和更多信息,请参阅:https://medium.com/@meysam.mahfouzi/understanding-future-in-dart-3c3eea5a22fb
答案 4 :(得分:0)
有两种方法可以从 Future
中获取值。
使用 async-await
:
int _value = 0; // Instance variable.
void func() async {
int value = await _yourFuture(); // Await on your future.
setState(() {
_value = value;
});
}
使用 then
:
int _value = 0; // Instance variable.
void func() {
_getPref().then((value) {
setState(() {
_value = value; // Future is completed with a value.
});
});
}
答案 5 :(得分:-2)
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
class ThreadExample implements Callable<String>{
@Override
public String call() throws Exception {
// TODO Auto-generated method stub
return "Ashish";
}
}
public class FutureThreadExample {
public static void main(String a[]) throws InterruptedException, ExecutionException {
ExecutorService executorService=Executors.newFixedThreadPool(1);
List <Future<String>>objList=new ArrayList<Future<String>>();
for(int i=0;i<10;i++) {
Future<String> obj=executorService.submit(new ThreadExample());
objList.add(obj);
}
for( Future<String> fut:objList) {
System.out.println(fut.get());
}
executorService.shutdown();
}
}