Flutter 如何使用 Future return value as if variable

Flutter how to use Future return value as if variable

我想获取 Future return 值并将其用作变量。 我有这个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 class。它说 dynamic.
如何获得 return 值并使用它?
我首先做错了吗? 任何帮助表示赞赏!

您可以简化代码:

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);
}
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();
    }


}

这样使用

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

这个函数returns未来价值

dbHelper.getUsers()

是这样写的

getUsers() async { .... }

要在 Daibaku 的原始问题上添加更多细节,这可能有助于澄清在 Flutter/dart 中使用 Futures,user 是:

final user = _fetchUserInfo(id);

如果不让编译器推断类型,那就是:

final Future<User> user = _fetchUserInfo(id);

获取并使用未来价值

Daibaku 问如何获取 user 的 return 值并使用它。

要在 Widget 中使用 user,您的 widget 必须 watch/observe 进行更改,并在更改时自行重建。

您可以使用大量样板代码手动执行此操作,或者您可以使用 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 在上面的例子中,同步地(即立即)returns 一个零 width/height 容器 Widget,而且还附加了一个观察者到你的未来 user,到知道未来数据何时到达。

user 最终更新为 "data" 时,FutureBuilder 的观察者会收到通知并调用 setState(),它会开始重建自身。现在 snapshot.hasDatatrueText(snapshot.data.userName) 是 returned 而不是空容器。


如果您没有在 Widget 元素树构建的同步世界中使用 user,而只是想打印出用于调试的值,您可以使用 then:[=29 附加观察者=]

user.then((u) => print(u.userName));

只需在上述答案基础上添加更多 explanation/description

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

调用一个 return 是 Future 的函数,不会阻塞你的代码,这就是为什么这个函数被称为异步的原因。相反,它将立即 return 一个 Future 对象,该对象最初是 未完成的

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

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

  1. 然后

  2. 等待

假设 getNews 函数 return 是 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

有两种方法可以从 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.
        });
      });
    }