0

我是 dart 和 Flutter 的新手,很想就我面临的算法问题获得一些建议。

我想将我的 Flutter 应用程序连接到蓝牙设备(该部分已完成,我已经连接)并以不均匀的间隔发送消息。我有一个列表中的消息,对于每个消息,我都知道我想在什么时间(毫秒)发送消息。

因此,假设排列了以下消息:

  • start在 0 毫秒
  • init_app在 100 毫秒
  • user_pick_x在 500 毫秒
  • user_start_x在 500ms (将在之后发送user_pick_x,应保证订单)
  • interrupt在 3500 毫秒

我找到了创建流的文档,但它总是谈论单个间隔值。https://dart.dev/articles/libraries/creating-streams

想法:

  • 从技术上讲,我可以传入Duration对象列表并使用自定义生成器async*以及消息字符串。
  • 或者,我可以将间隔设置为最低时间增量,并检查每个是否应该发送一条消息。在示例的情况下,这将是每 100 毫秒。

能够暂停/取消流也很好。这是流本身可以做的事情。

4

1 回答 1

0

我认为最简单的方法是以指定的时间间隔发出这些消息。就像是:

Future<void> _wait(int milliseconds) async =>
  await Future<void>.delayed(Duration(milliseconds: milliseconds));

Stream<String> generateMessages() async* {
  yield 'start';
  await _wait(100);
  yield 'init_all';
  await _wait(400);
  yield 'user_pick_x';
  yield 'user_start_x';
  await _wait(3000);
  yield 'interrupt';
}

void main() {
  generateMessages().listen((msg) {
    print('${DateTime.now()}: $msg');
  });
}

这将打印:

2021-07-25 10:21:21.429: start
2021-07-25 10:21:21.531: init_all
2021-07-25 10:21:21.934: user_pick_x
2021-07-25 10:21:21.934: user_start_x
2021-07-25 10:21:24.938: interrupt

如果您想确保流的侦听器异步接收事件 - 因此不干扰等待毫秒,您可以显式使用StreamController默认情况下异步调用侦听器(确保导入 dart:async --- dart:io仅在示例中用于sleep显示即使在阻塞操作中它也会与等待并行运行):

import 'dart:async';
import 'dart:io';

Future<void> _wait(int milliseconds) async {
  print('WAIT $milliseconds ms');
  await Future<void>.delayed(Duration(milliseconds: milliseconds));
}

Stream<String> generateMessages() {
  final controller = StreamController<String>(sync: false);
  controller.onListen = () async {
    controller.add('start');
    await _wait(100);
    controller.add('init_all');
    await _wait(400);
    controller.add('user_pick_x');
    controller.add('user_start_x');
    await _wait(3000);
    controller.add('interrupt');
  };
  return controller.stream;
}

void main() {
  generateMessages().listen((msg) {
    sleep(const Duration(milliseconds: 120));
    print('${DateTime.now()}: $msg');
  });
}
于 2021-07-25T08:21:59.733 回答