Flutter – 等待多个同步函数调用中的异步函数返回

huangapple go评论69阅读模式
英文:

Flutter - Waiting for an asynchronous function call return from multiple synchronous function calls

问题

我有一个异步函数,它被多次同步调用。

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

在内部,它弹出一个表单并等待它被提交或取消。

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

第一个提供的 Future 将首先弹出表单并等待返回。这没有问题。但我希望第二个 Future 先检查表单是否已经弹出。如果已经弹出,它只需等待它的完成并接收相同的返回值。

我知道从两次调用中获得相同的函数返回值听起来疯狂且不可能。我只是寻找一种方法来保持第二个 Future 的调用,并从其他地方触发它的完成。

请告诉我我错过了什么,我将提供所需的信息。

英文:

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.

答案1

得分: 0

看起来您想合并对异步操作的多次调用。使您的异步操作缓存它返回的 Future,并使后续调用直接返回该 Future。例如:

Future<Result>? _pending;

Future<Result> foo() {
   if (_pending != null) {
     return _pending!;
   }

   Future<Result> doActualWork() async {
     // 这里进行具体操作(比如显示表单)。
   }

   return _pending = doActualWork();
}

现在,无论您多少次使用 await foo();doActualWork() 最多只会执行一次。如果您希望允许 doActualWork() 被多次执行,只需合并并发调用,那么在 doActualWork 返回之前立即将 _pending = null;

英文:

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&lt;Result&gt;? _pending;

Future&lt;Result&gt; foo() {
   if (_pending != null) {
     return _pending!;
   }

   Future&lt;Result&gt; 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.

答案2

得分: 0

我尝试使用ValueNotifier。不幸的是,ValueNotifier.addListener() 只接受一个 VoidCallback。就目前而言,这是我的解决方案。仍然在寻找更好的方法来替代循环。

Future future() async{
  if(ison) await Future.doWhile(() async {
    await Future.delayed(Duration(seconds: 1));
    return ison;
  });
  else{
    ison = true;
    result = ... //弹出表单
    ison = false;
  }
  return await result;
}
英文:

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;
  }

huangapple
  • 本文由 发表于 2023年2月8日 16:12:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/75382897.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定