34

我想获得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
如何获得返回值并使用它?
我首先做错了吗?任何帮助表示赞赏!

4

6 回答 6

51

您可以简化代码:

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);
}
于 2018-08-29T02:45:50.950 回答
9

像这样使用

var username;
dbHelper.getUsers().then((user) {
  username = user.getName;
});

此函数返回未来值

dbHelper.getUsers()

它是这样写的

getUsers() async { .... }
于 2019-08-22T17:28:31.310 回答
7

只需在上述答案上添加更多解释/描述

当一个函数返回一个 Future 时,意味着它的结果需要一段时间才能准备好,并且结果将在未来可用。

调用返回 Future 的函数不会阻塞您的代码,这就是该函数被称为异步的原因。相反,它将立即返回一个 Future 对象,该对象起初是uncompleted

Future<T>意味着异步操作的结果将是类型T。例如,如果一个函数返回Future<String>,这意味着将来它会提供一个字符串给你。

只有当 Future 为 时,Future 的结果才可用completed。您可以使用以下任一关键字访问 Future 的结果:

  1. 然后

  2. 等待

假设 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

于 2021-01-09T03:30:54.153 回答
4

为了在 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在上面的示例中,同步(即立即)返回一个零宽度/高度的容器小部件,但还会将观察者附加到您的 future user,以了解 Future 数据何时到达。

user最终用“数据”更新时,FutureBuilder会通知观察者并调用setState(),这将开始重建自身。现在返回的snapshot.hasDatatrue,Text(snapshot.data.userName)而不是空的 Container。


如果您没有user在 Widget Element 树构建的同步世界中使用,而只是想打印出调试值,您可以使用以下方法附加观察者then

user.then((u) => print(u.userName));
于 2020-04-20T21:04:13.797 回答
0

有两种方法可以从 a 中获取值Future

  1. 使用async-await

    int _value = 0; // Instance variable.
    
    void func() async {
      int value = await _yourFuture(); // Await on your future.
      setState(() {
        _value = value;
      });
    }
    
  2. 使用then

    int _value = 0; // Instance variable.
    
    void func() {
      _getPref().then((value) {
        setState(() {
          _value = value; // Future is completed with a value.
        });
      });
    }
    
于 2021-07-21T16:30:01.620 回答
-15
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();
    }


}
于 2019-06-16T09:25:36.893 回答