skip to Main Content

I have an async function which is called multiple times synchoronusly.

List response = await Future.wait([future, future])

Inside, it popups a form and waiting for it to be submitted or cancelled.

var val = await Navigator.push(
  context, 
  MaterialPageRoute(builder : (context) => const TheForm())
);

The first served Future will popup the form first and waiting for the return. No problem with that. But I want the second Future to check first if the form is already popped up. If it is, it just waiting for it to conclude and receive the same returned value.

I’m aware that receiving same function return from two calls sounds crazy and impossible. I’m just looking for a way to hold the second Future call on and trigger to conclude it from somewhere else.

Kindly tell me what I was missing and I’ll provide the required information.

2

Answers


  1. Chosen as BEST ANSWER

    I try to use ValueNotifier's. Unfortunately ValueNotifier.addListener() only accept a VoidCallback. As for now, this is my solution. Still looking for a better way to replace the loop.

      Future future() async{
        if(ison) await Future.doWhile(() async {
          await Future.delayed(Duration(seconds: 1));
          return ison;
        });
        else{
          ison = true;
          result = ... //Popup form
          ison = false;
        }
        return await result;
      }
    

  2. It sounds like you want to coalesce multiple calls to an asynchronous operation. Make your asynchronous operation cache the Future it returns, and make subsequent calls return that Future directly. For example:

    Future<Result>? _pending;
    
    Future<Result> foo() {
       if (_pending != null) {
         return _pending!;
       }
    
       Future<Result> doActualWork() async {
         // Stuff goes here (such as showing a form).
       }
    
       return _pending = doActualWork();
    }
    

    Now, no matter how many times you do await foo();, doActualWork() will be executed at most once. (As pskink noted in a comment, AsyncMemoizer from package:async can do this for you.)

    If you instead want to allow doActualWork() to be executed multiple times and just to coalesce concurrent calls, then make doActualWork set _pending = null; immediately before it returns.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search