[英]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
,在已添加到Map
的Future
上,它将很快被删除。
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 thethen()
(but it does forawait
), but isn't there a remote case where it might get to theawait
part, but thefuture
is NOT inside theMap
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.