Maksym Moros
Maksym Moros

Reputation: 529

Flutter: 'Future.wait' multiple async functions in parallel VS 'await' one at a time. <= different results

I recently learned of the fabulous way of waiting for multiple async functions to complete using Future.wait([asyncFuncOne(), asyncFunctwo()])

However, I noticed two different outcomes when running either of these blocks of code. One awaiting each function to finish, the other using Future.wait for parallel processing. What am I doing wrong?

Method 1:

    await msm.initProfileData();
    await msm.initActivityFeed();
    await msm.getRecentlyActiveUsers();
    await msm.getRecommendedUsers();
    await msm.getGroups();
    await msm.getFollowing();
    await msm.getFollowers();

Method 2:

    await Future.wait([
      msm.getFollowing(),
      msm.initProfileData(),
      msm.initActivityFeed(),
      msm.getRecentlyActiveUsers(),
      msm.getRecommendedUsers(),
      msm.getGroups(),
      msm.getFollowers(),
    ]);

in Method 1, all the async functions complete before my apps home screen appears. In Method 2 the home screen appears before all the async functions complete.

Cheers and thanks in advance.

EDIT: Additional code example.

@override
  void initState() {
    super.initState();
    googleSignIn.onCurrentUserChanged.listen((account) {
      handleSignIn(account);
    }, onError: (err) {
      print('Error signing in: $err');
    });
    googleSignIn.signInSilently(suppressErrors: false).then((account) {
      handleSignIn(account);
    }).catchError((err) {
      setState(() => _showSignIn = true);
      print('Error signing in: $err');
    });
  }

  handleSignIn(GoogleSignInAccount account) async {
    if (account != null) {
      await createUserInFirestore();
      setState(() {
        isAuth = true;
      });
    } else {
      setState(() {
        isAuth = false;
        _showSignIn = true;
      });
    }
  }

  createUserInFirestore() async {
    final GoogleSignInAccount user = googleSignIn.currentUser;
    DocumentSnapshot doc = await usersRef.document(user.id).get();
    //...
    //do stuff
    //...
    await someFunc1(); //Method1
    // await comeFunc2(); //Method2
    //do more stuff
  }

  someFunc1() async {
      msm.asyncfunc1();
      msm.asyncfunc2();
  }

  someFunc2() async {
      await Future.wait([
          msm.asyncFunc1(),
          msm.asyncFunc2(),
      ]);
  }

  @override
  Widget build(BuildContext context) {
    return isAuth ? buildAuthScreen() : buildUnAuthScreen();
  }

Upvotes: 5

Views: 6090

Answers (1)

Omatt
Omatt

Reputation: 10463

Using Future.wait(List<Future>) will wait for all the async operations without sequence as mentioned in the docs. While using await consecutively, it'll wait for the first await async operation to finish before running the next await async operation. If you have a prerequisite output before running the next async operation, it's better to use await async in sequence instead.

Upvotes: 4

Related Questions