Flutter:我可以调用相同的 Future,首先使用 "then()",然后使用 "await",而不会出现竞争条件问题吗?

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

我在 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));

我们在这个Map中添加了一个future之后,我们通过调用then()来执行future, 因为我们希望在 future 完成后,将 futureMap.

中删除

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

我无法真正理解这是多么好的代码,因为在我看来,当使用 then() 调用 Future 时,我知道代码执行不会停止 then()(但它适用于 await),但是否存在远程情况,它可能到达 await 部分,但 future 不在 Map 内不再,因为它已经被删除了?

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

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?

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

引用的代码通常不应该是活泼的。 Futures 通常是异步的;即使 Future 的计算已经完成,.then() 回调也不会执行,直到 Dart 运行时 returns 到事件循环,在这种情况下会发生在 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 class 实现了 Future 接口,但在注册时同步执行其 .then() 回调。然而,这是相当不寻常的(这就是 SynchronousFuture 的文档明确不鼓励使用它的原因)。为此,NetworkProvider().getRecentPodcasts 实现必须明确地 return 一个 SynchronousFuture(或一些等效的实现)。