skip to Main Content

There are two pages: page1 and page2.

page1 pass List<Future> to page2, page2 execute these futures.

Below is all the source code:

class _Page1 extends StatelessWidget {
  const _Page1({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('page 1'),
      ),
      body: ElevatedButton(
        child: Text('push page 2'),
        onPressed: () {
          Navigator.push(
            context,
            MaterialPageRoute(
              builder: (context) => _Page2(
                requests: [_load1(), _load2()],
              ),
            ),
          );
        },
      ),
    );
  }

  Future<void> _load1() {
    return Future.delayed(Duration(seconds: 1), () {
      log('load1 finish');
    });
  }

  Future<void> _load2() {
    return Future.delayed(Duration(seconds: 2), () {
      log('load2 finish');
    });
  }
}

class _Page2 extends StatelessWidget {
  const _Page2({Key? key, required this.requests}) : super(key: key);

  final List<Future> requests;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('page 2'),
      ),
      body: ElevatedButton(
        child: Text('future wait'),
        onPressed: () {
          Future.wait(requests).then((value) {
            log('all finish');
          });
        },
      ),
    );
  }
}

The first time click page2 button, log: load1 finish, load2 finish, all finish.

But after the first time, it’s only log all finish.

Why? And how to change it to log load1 finish, load2 finish, all finish everytime click page2 button?

2

Answers


  1. Why?

    Because they finished. They are done. If you want to run them again, you have to create new Futures.

    Login or Signup to reply.
  2. Your list requests in _Page2 is a list of future and not a function, meaning it is only returning the one-time result. So when you say Future.wait(requests), you are telling it to just listen for the return result which was already done, but not asking it to execute the function.

    If you want to execute the function after clicking the ‘future wait’ button, you have to turn the list into a Function.

    final List<Function> requests;
    

    So now you pass the object from page1 like this:

      onPressed: () {
          _load1();
          _load2();
          Navigator.push(
            context,
            MaterialPageRoute(
              builder: (context) => _Page2(
                requests: [_load1, _load2],
              ),
            ),
          );
        },
    

    So now you call the future wait to do its function after executing the functions in your request list like this:

              Future.wait(requests.map((e) => e())).then((value) {
                log('all finish');
                debugPrint('all finish');
              });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search