首页 > 解决方案 > Flutter:我可以调用同一个 Future,首先使用“then()”,然后是“await”,而不会引发竞争条件问题吗?

问题描述

我在 SO 上遇到了这段代码:

编辑:以下代码片段功能齐全,我试图了解除了“工作”之外,它是否会由于可能的竞争条件而导致错误

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

我不能把头绕在一个部分上:

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

future在这里,在我们向 this添加 a 之后,我们通过调用来Map执行,因为我们希望在完成之后,从.futurethen()futurefutureMap

到这里一切都清楚了,但在下一行,我们调用await,Future已添加到 的Map,很快就会被删除。

我无法真正理解这是如何成为好的代码,因为在我看来,当使用 调用 Future 时then(),我知道代码执行不会then()await它可能到达await零件的情况,但它已经future不在里面Map了,因为它已经被移除了?

或者这永远不会发生,如果是这样,你能解释一下内部工作原理吗,这样我就可以完全掌握这个概念并改进我的代码库

标签: flutterdartasync-awaitfuture

解决方案


我无法真正理解这是如何成为好的代码,因为在我看来,当使用 调用 Future 时then(),我知道代码执行不会then()await它可能到达await零件的情况,但它已经future不在里面Map了,因为它已经被移除了?

Future.then()不执行Future的计算。Future.then()只注册一个回调。

引用的代码通常不应该是活泼的。Futures 通常是异步的;即使Future' 的计算已经完成,.then()回调也不会执行,直到 Dart 运行时返回到事件循环,在这种情况下,事件循环将发生await在行。你可以观察到:

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

这将打印:

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

在病态的情况下,代码有可能(但不太可能)是活泼的。例如,Flutter 提供了一个SynchronousFuture实现接口的类,但在注册时会同步Future执行其回调。.then()然而,这是相当不寻常的(这就是为什么文档SynchronousFuture明确不鼓励使用它的原因)。为此,NetworkProvider().getRecentPodcasts实现必须显式返回一个SynchronousFuture(或一些等效的实现)。


推荐阅读