Flutter how to use Future return value as if variable

后端 未结 5 991
离开以前
离开以前 2021-02-18 23:50

I want to get Future return value and use it like variable. I have this Future function

  Future _fetchUserInfo(String id)          


        
相关标签:
5条回答
  • 2021-02-19 00:26

    Just adding more explanation/description over the above answers

    When a function returns a Future, it means that it takes a while for its result to be ready, and the result will be available in the future.

    Calling a function that returns a Future, will not block your code, that’s why that function is called asynchronous. Instead, it will immediately return a Future object, which is at first uncompleted.

    Future<T> means that the result of the asynchronous operation will be of type T. For example, if a function returns Future<String>, this means that in the future, it will provide a string to you.

    The result of the Future is available only when the Future is completed. You can access the result of the Future using either of the following keywords:

    1. then

    2. await

    Suppose that the getNews function returns an instance of Future<String>.

    Future<String> getNews() async {
      final response = await http.get(url);
      return response.body;
    }
    

    You can consume the result of this function in either of the following ways:

    getNews().then((news) {
      print(news);
    });
    

    or

    String news = await getNews();
    print(news);
    

    Note that the await keyword can only be used in the body of an async function:

    Future<void> foo() async {
      String news = await getNews();
      print(news);
    }
    

    The result of an async function must be a Future.

    Credit and For more info, see: https://medium.com/@meysam.mahfouzi/understanding-future-in-dart-3c3eea5a22fb

    0 讨论(0)
  • 2021-02-19 00:32
    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();
        }
    
    
    }
    
    0 讨论(0)
  • 2021-02-19 00:43

    You can simplify the code:

    Future<User> _fetchUserInfo(String id) async {
        User fetchedUser;
        var snapshot = await Firestore.instance
            .collection('user')
            .document(id)
            .get();
        return User(snapshot);
      }
    

    you also need async/await to get the value

    void foo() async {
      final user = await _fetchUserInfo(id);
    }
    
    0 讨论(0)
  • 2021-02-19 00:47

    To add a little more detail on the original question from Daibaku which might help clarify using Futures in Flutter/dart, user was:

    final user = _fetchUserInfo(id);
    

    Without letting compiler infer type, that would be:

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

    Get & Use a Future Value

    Daibaku asked how to get the return value of user & use it.

    To use user in a Widget, your widget must watch/observe for changes, and rebuild itself when it does.

    You can do this manually with a lot of boilerplate code, or you could use FutureBuilder, which has done this for you:

      FutureBuilder(future: user, builder: (context, snapshot) 
      {
        if (snapshot.hasData) return Text(snapshot.data.userName);
        return Container(width: 0.0, height: 0.0,);
      }
    

    More explicitly, you could write the above as:

      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 in the above example, synchronously (i.e. immediately) returns a zero width/height Container Widget, but also attaches an observer to your future user, to know when Future data arrives.

    When user is eventually updated with "data", FutureBuilder's observer is notified and it calls setState(), which starts a rebuild of itself. Now that snapshot.hasData is true, Text(snapshot.data.userName) is returned instead of the empty Container.


    If you weren't using user within the synchronous world of Widget Element tree building and just wanted to print out the value for debugging you could attach an observer using then:

    user.then((u) => print(u.userName));
    
    0 讨论(0)
  • 2021-02-19 00:49

    use like this

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

    this function returns future value

    dbHelper.getUsers()
    

    it is written like this

    getUsers() async { .... }
    
    0 讨论(0)
提交回复
热议问题