skip to Main Content

I build a widget on my frontpage which relys on information I receive from firebase.

Because this widget can not display properly without the information from the database (dates, picture urls etc.), there are two futures which have to complete (to fetch the data from the database) before this widget can be rendered.

Right now, I call a function from my frontpage’s setState method which calls an async function getAllFutures() in which I execute the following code:

await Future.wait([
  globals.checkExistingWochenplan(),
  globals.getWochenplan(kw: 34)
]).then((value) {
  print(value);
  print("DONE");
});

From what I understood about Future.wait (correct me if I am wrong), this method, when executed, blocks the main thread until all futures are completed, which is exactly what I want, because I rely on the data. Is that right? Because, when I check out my debug consoles messages, the rest of my app keeps executing while the futures in Future.wait get executed.

Can someone tell me what I am doing wrong here/weather I use Future.wait correctly or not?

The print statement in the .then method afterwards returns null twice btw, but that is probably because of the futures themselves.

I am looking forward to your replys.

Regards
Goku

2

Answers


  1. The Future.wait() is used to wait for multiple futures to complete and collects their results. Returns a future which will complete once all the provided futures have completed, either with their results, or with an error if any of the provided futures fail. But you shouldn’t mix then and await, it’s better for consistency to use either/or. For example:

     void main()  {
     Future.wait([delayedNumber(), delayedString()])
     .then((value) {
      print(value);
      print("DONE");
    });
       print("printed first outside of future");
    }
    
    
    Future<int> delayedNumber() async {
      await Future.delayed(const Duration(seconds: 2));
      return 2;
    }
    
    Future<String> delayedString() async {
      await Future.delayed(const Duration(seconds: 2));
      return "result";
    }
    

    which would give you:

    printed first outside of future
    [2, result]
    DONE
    

    While if you use async/await:

     void main() async {
     var value = await Future.wait([delayedNumber(), delayedString()]);
     print(value);
     print("printed at the end");
    }
    
    
    Future<int> delayedNumber() async {
      await Future.delayed(const Duration(seconds: 2));
      return 2;
    }
    
    Future<String> delayedString() async {
      await Future.delayed(const Duration(seconds: 2));
      return "result";
    }
    

    You would get the following:

    [2, result]
    printed at the end
    

    You can read more about it here:

    Asynchronous programming: futures, async, await

    wait static method

    Login or Signup to reply.
  2. You’re wrong. Future.wait does not block the main thread, in fact, there is nothing called main thread in Dart. Dart is single threaded, which means it uses an event loop. That’s why your app keeps working during an awaited Future.

    this.isLoading = true;
    setState(() {});
    final value = await Future.wait([
      globals.checkExistingWochenplan(),
      globals.getWochenplan(kw: 34)
    ]);
    this.isLoading = false;
    this.image = value.first;
    this.dates = value.last;
    setState(() {});
    

    One approach (amongst many others) to use data from Future in UI is to use flags like isLoading above and display the widget that require the data once the flag is toggled.

    Somewhere in your build tree, you should have something like (pseudocode)

     (isLoading) ? CircularProgressIndicator() : Container(child: Image(image: this.image))
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search