Search code examples
flutterloopsasynchronousfuturewait

How to use a loop to give `Future.wait()` a list o Futures


I'm using Future.wait() to get some data like in the code below:
I call the function Future.delayed() to wait 1 second between every call because I have a limit set to 1 request per second

    await Future.wait([

        Future.delayed(const Duration(milliseconds: 1000))
            .then((value) => getPartNumber(1)
            .then((value) => addPartToList((value.data)))),

        Future.delayed(const Duration(milliseconds: 2000))
            .then((value) => getPartNumber(2)
            .then((value) => addPartToList((value.data)))),

        Future.delayed(const Duration(milliseconds: 3000))
            .then((value) => getPartNumber(3)
            .then((value) => addPartToList((value.data)))),

        Future.delayed(const Duration(milliseconds: 4000))
            .then((value) => getPartNumber(4)
            .then((value) => addPartToList((value.data)))),

    ]);

So what I wanna do is to use a loop instead of repeating the call manually 4 times


Solution

  • Why can't you just use a for loop and wait 1 second in between to not exceed the rate limit.

    for(int i = 1; i <= 4; i++){
      await Future.delayed(const Duration(seconds: 1));
      await getPartNumber(i).then((value) => addPartToList(value.data));
    }
    

    This also ensures that no more than one request per second comes in, as the time in between is waited. Or if you want the waiting time to be handled the same way as in your code, the following also works:

    await for(var i in Stream.periodic(const Duration(seconds: 1), (i)=>i).take(5)){
      if(i == 0) continue;
      await getPartNumber(i).then((value) => addPartToList(value.data));
    }
    

    Or if you really want to do it with Future.wait(), which I personally don't like, here's how to do it:

    await Future.wait(
      Iterable.generate(4, (i)=>Future.delayed(const Duration(seconds: i + 1))
        .then((value) => getPartNumber(i + 1))
        .then((value) => addPartToList(value.data))
    );
    

    or

    await Future.wait([
      for(int i = 1; i <= 4; i++)
        Future.delayed(const Duration(seconds: i))
          .then((value) => getPartNumber(i)
          .then((value) => addPartToList(value.data))
    ]);