如何(以及应该如何?)从 Dart 的 await-for 循环中取消流?

Ale*_*uca 3 dart

我有一个关于 Dart 流的问题,如下。当我通过它的listen()方法使用 Stream 时,我可以将返回的结果分配listen给一个变量并在我完成后取消订阅(例如一个dispose()方法)。我应该如何取消await-for循环监听的流?

只是为了澄清,我不打算更改执行流程(例如,取消 Stream 以便await-for运行后的代码),而是在我不再需要 Stream 时防止内存泄漏。

lrn*_*lrn 5

取消由 an 创建的订阅的唯一方法await for是退出循环。

此刻你使用像的控制流程操作退出循环returnbreakcontinuethrowrethrow(或者yield在操作async*功能,其中在流上收听已取消)时,cancel上下面的订阅方法被自动取消。

如果循环自行终止,那是因为流已经完成,所以没有什么可担心的。

如果你想长时间在循环内进行计算,然后退出循环,那么我建议重构代码,改为在循环外进行计算。那是:

await for (var event in stream) {
  if (event.isTheOne) {
    await longComputation(event);
    break;
  }
}
Run Code Online (Sandbox Code Playgroud)

将使流保持活动状态并暂停直到longComputation完成。相反,我会做类似的事情:

var theOne = null;
await for (var event in stream) {
  if (event.isTheOne) {
    theOne = event; 
    break; 
  }
}
if (theOne != null) await longComputation(theOne); 
Run Code Online (Sandbox Code Playgroud)

或类似的东西。


Ale*_*dar 1

我觉得How should I go about canceling a Stream有点拼写错误。如果listen您正确编写了方法cancel the Subscription,因为您取消了订阅,而不是蒸汽本身。

listen()是非阻塞的,它创建一个订阅,注册一个回调,然后继续执行当前代码块中的下一个代码。该await for构造是阻塞的,它不会创建对流的订阅。await for在流关闭之前,代码的执行不会超出范围。此处举例说明。因此,根据我的理解,您无需担心await for.