颤抖如何像变量一样使用Future返回值

时间:2018-08-29 02:31:15

标签: firebase dart flutter google-cloud-firestore

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

6 个答案:

答案 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.hasDatatrue,将返回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 的结果:

  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

答案 4 :(得分:0)

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

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


}