有没有办法让Dart Streams做类似的事情
连续多次await stream.first
,使用有点像堆栈/队列的流?
据我了解,你可以在现有的Single-substription流上使用asBroadcastStream来做到这一点,但我觉得这并不理想。
也许有一种缓冲原语带有一些Rx包或类似的东西?
我的用例如下:
我有StreamChannel
(IOWebSocketChannel
),我想按特定顺序发送/接收消息。
即:
Send Message0
Receive Message1
Send Message2
Receive Message3
我确信Message1
只会在服务器收到Message0
后到达
(等Message2
和Message3
)
答案 0 :(得分:7)
对于基于推送的事件和基于拉取的资源读取,Dart具有单一抽象的优势(在我看来,不利)。这导致了许多其他混淆,例如"Do I have to cancel stream subscriptions"。
在基于推送的模型中,请说:
abstract class Element {
Stream<MouseEvent> get onClick;
}
当发生点击时,该类通知。可能存在介于0和字面无限点击事件之间的任何位置,并且通常不希望以与读取资源相同的方式缓冲或处理它们(特别是考虑到Dart是单线程的)。 另一个注意事项:此流的任何订阅者数量是完全有效的(多个类可能有兴趣知道点击何时发生)。
另一方面,有一个基于拉的模型,比如读取文件:
abstract class File {
Stream<String> readLines();
}
在这个的情况下,您可能希望逐行处理,甚至可能在您点击某个字符串后停止,并且肯定希望通过EOF(通常由“完成”事件,或流闭幕,在惯用的Dart中)。 另一个注意事项:拥有超过1个订阅者的不有效 - 这会很快变得棘手。
对于您的特定问题,您似乎想:
好的,让我们来看看你问题的具体细节:
据我了解,你可以在现有的Single-substription流上使用asBroadcastStream来做到这一点,但我觉得这并不理想。
非常不理想。单订阅流(我称之为“资源流”,如上面的readLines
调用)自动缓冲事件并等待订阅者。 不接收一行文本是非常糟糕的,因为在文件被读取之后订阅发生了。
另一方面,广播流不缓冲事件。因此,如果您根据时间安排等问题采用您的方法,您可能会发现自己正在丢失事件。
这里有几个选项。没有一个是完美的,但他们可能会有所帮助:
package:stream_transform
包有一组Stream
常用的转换,包括一些受RX启发的转换。
package:async
包具有其他用于处理异步代码的实用程序。具体来说,您可能会发现StreamQueue
完全符合您的要求:
Future<void> processEvents(Stream<String> inputStream) async {
var queue = new StreamQueue(inputStream);
while (await queue.hasNext) {
var next = await queue.next;
// Insert processing here.
}
}
我发现自己希望StreamQueue
在 dart:async
中是,并且用于资源和流的Stream
之间没有共享接口用于事件,但今天这是一个不错的方法。
干杯!