我怀疑我对Dart中的Stream
的理解可能有一些漏洞...
我遇到一种情况,我想让Dart应用程序响应间歇性输入(可能立即建议使用Streams
或Future
s)。我可以使用 listener 函数实现我想要的行为,但是我想知道如何以更好,更Dart esque 的方式执行此操作。
作为一个简单的示例,下面的(运行中)程序会监听用户的键盘输入,并在每当按下空格键时向文档中添加一个div元素,其中包含自上一个空格以来所键入的内容。
import 'dart:html';
main() {
listenForSpaces(showInput);
}
void listenForSpaces(void Function(String) listener) {
var input = List<String>();
document.onKeyDown.listen((keyboardEvent) {
var key = keyboardEvent.key;
if (key == " ") {
listener(input.join());
input.clear();
} else {
input.add(key.length > 1 ? "[$key]" : key);
}
});
}
void showInput(String message) {
document.body.children.add(DivElement()..text = message);
}
我想做的是根据我正在听的Stream
创建一个新的Stream
(在上面的示例中,创建一个新的{{1} }来自Stream
)。换句话说,我可以将程序设置为:
onKeyDown
我怀疑有一种创建var myStream = ...
myStream.listen(showInput);
的方法,然后在不同的时间和位置将元素插入其中或要求它发出一个值:感觉好像我缺少一些简单的东西。无论如何,任何对文档的帮助或指导将不胜感激。
答案 0 :(得分:3)
使用async*
函数从现有流中创建新流非常容易。
对于普通流,我只想做:
Stream<String> listenForSpaces() async* {
var input = <String>[];
await for (var keyboardEvent in document.onKeyDown) {
var key = keyboardEvent.key;
if (key == " ") {
yield input.join();
input.clear();
} else {
input.add(key.length > 1 ? "[$key]" : key);
}
}
}
async*
函数将暂停传播到基础流,并且可能在yield
期间暂停源。
那可能不是您想要的,因为暂停DOM事件流可能会导致您错过事件。对于DOM流,我可能更喜欢采用以上基于StreamController
的解决方案。
答案 1 :(得分:1)
有几种方法,并且有一个完整的软件包rxdart
用于允许各种事物。
只有最终用户才应使用listen
,并且只有在您需要明确地取消订阅时,才应使用forEach
如果您要像示例中那样操作事件,请使用map
。
答案 2 :(得分:0)
我原本并不打算回答自己的问题,但此后我在dartlang creating streams文章中找到了对该问题的非常简单的答案;以防对他人有帮助:
具体来说,如果我们想创建一个流,可以在代码中的任意时间和位置插入元素,则可以通过StreamController类来实现。此类的实例具有 DATE BBG FLAG DATE_DIFF NEW_DATE PICKED
0 2014-03-04 1333 1 -31.0 2014-04-03 NaT
1 2014-04-04 1333 0 -91.0 2014-04-04 2014-04-04
2 2014-07-04 1333 1 -31.0 2014-04-07 NaT
3 2014-08-04 1333 1 -31.0 2014-04-08 NaT
4 2014-09-04 1333 1 -30.0 2014-04-09 NaT
5 2014-10-04 1333 1 -31.0 2014-04-10 NaT
6 2014-11-04 1333 1 204.0 2014-04-11 NaT
7 2014-04-14 1333 0 -1.0 2014-04-14 2014-04-14
8 2014-04-15 1333 0 -1.0 2014-04-15 2014-04-15
9 2014-04-16 1333 0 -1.0 2014-04-16 2014-04-16
方法;我们可以简单地使用实例的add
属性作为流。
例如,我问题中的代码可以重写为:
stream
(如文章中所述,如果要像这样从头开始设置流,则需要小心,因为没有什么可以阻止我们向没有关联的活动订户;已插入的流中插入项目。在这种情况下,项目将被缓冲,这可能导致内存泄漏。)