从Dart中的流创建新流

时间:2018-11-04 05:03:38

标签: stream dart future

我怀疑我对Dart中的Stream的理解可能有一些漏洞...

我遇到一种情况,我想让Dart应用程序响应间歇性输入(可能立即建议使用StreamsFuture 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); 的方法,然后在不同的时间和位置将元素插入其中或要求它发出一个值:感觉好像我缺少一些简单的东西。无论如何,任何对文档的帮助或指导将不胜感激。

3 个答案:

答案 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

(如文章中所述,如果要像这样从头开始设置流,则需要小心,因为没有什么可以阻止我们向没有关联的活动订户;已插入的流中插入项目。在这种情况下,项目将被缓冲,这可能导致内存泄漏。)