简体   繁体   English

Flutter:我可以调用相同的 Future,首先使用“then()”,然后是“await”,而不会引发竞争条件问题?

[英]Flutter: can l call the same Future, first with "then()" followed by "await", without incurring in race condition issues?

I came across this piece of code on SO:我在 SO 上遇到了这段代码:

EDIT:the following code snippet is fully functional, I'm trying to understand if beside "working", can it lead to errors due to a possible race condition编辑:以下代码片段功能齐全,我试图了解除了“工作”之外,它是否会由于可能的竞争条件而导致错误

  if (!_downloaders.containsKey(page)) {
    _downloaders[page] = NetworkProvider().getRecentPodcasts(page);
    _downloaders[page].then((_) => _downloaders.remove(page));
  }
  final podcasts = await _downloaders[page];

and I cannot wrap my head around one part:我不能把头绕在一个部分上:

_downloaders[page].then((_) => _downloaders.remove(page));

here after we added a future to this Map , we execute the future by calling then() , because we want that after the future has finished, the future is removed from the Map .在这里,在我们为这个Map添加了一个future之后,我们通过调用then()来执行future ,因为我们希望在future完成之后,从Map中删除future

Here all is clear, but on the next line, we call await , on the Future that has been added to the Map , and which will be removed soon.这里一切都清楚了,但在下一行,我们调用await ,在已添加到MapFuture上,它将很快被删除。

I cannot really understand how this is good code, as it looks to me that when the Future is called with the then() , I know that the code execution doesn't stop for the then() (but it does for await ), but isn't there a remote case where it might get to the await part, but the future is NOT inside the Map anymore, as it has been already removed?我无法真正理解这是如何成为好的代码,因为在我看来,当使用then()调用 Future 时,我知道then() () 的代码执行不会停止(但它会为await停止),但是是否存在可能到达await部分的远程情况,但future不再位于Map内部,因为它已经被删除了?

Or this can never happen, and if so, can you explain me the inner workings, so I can fully graps this concept and improve my codebase或者这永远不会发生,如果是这样,你能解释一下内部工作原理吗,这样我就可以完全掌握这个概念并改进我的代码库

I cannot really understand how this is good code, as it looks to me that when the Future is called with the then() , I know that the code execution doesn't stop for the then() (but it does for await ), but isn't there a remote case where it might get to the await part, but the future is NOT inside the Map anymore, as it has been already removed?我无法真正理解这是如何成为好的代码,因为在我看来,当使用then()调用 Future 时,我知道then() () 的代码执行不会停止(但它会为await停止),但是是否存在可能到达await部分的远程情况,但future不再位于Map内部,因为它已经被删除了?

Future.then() does not execute the Future 's computation. Future.then()不执行Future的计算。 Future.then() only registers a callback. Future.then()只注册一个回调。

The cited code usually shouldn't be racy.引用的代码通常不应该是活泼的。 Future s are normally asynchronous; Future通常是异步的; even if the Future 's computation is already complete, the .then() callback will not execute until the Dart runtime returns to the event loop, which in this case would happen at the await line.即使Future的计算已经完成, .then()回调也不会执行,直到 Dart 运行时返回到事件循环,在这种情况下,这将发生在await行。 You can observe this:你可以观察到:

void main() async {
  print('Constructing Future');
  var future = Future.sync(() => print('Ran future'));
  print('Constructed Future; registering callback');
  // ignore: unawaited_futures
  future.then((_) => print('Ran .then() callback'));
  print('Registered callback; awaiting');
  await future;
  print('Done');
}

which will print:这将打印:

Constructing Future
Ran future
Constructed Future; registering callback
Registered callback; awaiting
Ran .then() callback
Done

It's possible (but unlikely) that the code could be racy in pathological cases.在病态的情况下,代码有可能(但不太可能)是活泼的。 For example, Flutter provides a SynchronousFuture class that implements the Future interface but executes its .then() callback synchronously upon registration.例如,Flutter 提供了一个SynchronousFuture class,它实现了Future接口,但在注册时同步执行其.then()回调。 However, that is rather unusual (and which is why the documentation for SynchronousFuture explicitly discourages using it).然而,这是相当不寻常的(这就是为什么SynchronousFuture的文档明确不鼓励使用它的原因)。 For that to happen, the NetworkProvider().getRecentPodcasts implementation would have to explicitly return a SynchronousFuture (or some equivalent implementation).为此, NetworkProvider().getRecentPodcasts实现必须显式返回SynchronousFuture (或某些等效实现)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM