如何根据您在 Dart 中无法控制的 Stream 返回 Future?
Posted
技术标签:
【中文标题】如何根据您在 Dart 中无法控制的 Stream 返回 Future?【英文标题】:How do you return a Future based off a Stream you don't control in Dart? 【发布时间】:2014-04-09 04:42:18 【问题描述】:我有一种情况,我期望来自 Stream
的单个值,但因为它是由浏览器提供的,所以我不能依赖简单地调用 streamSub.single
。目前,我正在创建一个显式的StreamController
,这样我就可以轻松地从中生成一个Future
,同时保证它只会得到一个响应。然而,这最终比我预期的要设置的开销要多得多,这让我觉得我错过了一些东西。当前代码如下:
StreamController<String> streamCtrlr = new StreamController<String>();
var popup = window.open(targetUrl, "Auth Window");
//The popup above will call window.opener.postMessage, so listen for messages
StreamSubscription sub = window.onMessage.listen(null);
sub.onData((Event)
/* Logic goes here */
sub.cancel();
popup.close();
streamCtrlr.add(Event.data);
streamCtrlr.close();
);
return streamCtrlr.stream.single;
如何重写此代码,从而不需要中介 StreamController
?
【问题讨论】:
【参考方案1】:
为什么你不能依靠打电话streamSub.single
?是因为可能有不止一条消息吗?
您的示例代码在所有情况下都选择第一个事件,因此要获得相同的行为,您可以使用window.onMessage.first
而不是window.onMessage.single
。
如果没有第一个事件,它仍然会导致错误(但我认为 DOM 事件处理程序不会发生这种情况 - 它们从不发送完成事件),否则它将给出一个由第一个事件完成的未来。
您还想提取事件数据,因此您可能需要:
return window.onMessage.first.then((event)
/* Logic goes here */
popup.close();
return event.data;
);
【讨论】:
是的,我对使用 sub.single 持谨慎态度,因为管道中可能会有多条消息。我实际上首先尝试过,但它没有触发第一个 postMessage 调用的 onData ,第二个引发了错误。我会先尝试流。当使用 stream.first 时,它是返回带有 自订阅 以来的第一个事件的未来,还是返回自创建流以来的第一个事件(在这种情况下意味着自 DOM 加载以来)?跨度> 按照@lrn 的建议,我选择使用firstWhere
并使用布尔闭包来检查消息的来源,以确保它来自我期望的域。完美运行! =D
我相信 DOM 流充当广播流,因此它们不应缓冲您收听之前的事件。以上是关于如何根据您在 Dart 中无法控制的 Stream 返回 Future?的主要内容,如果未能解决你的问题,请参考以下文章
如何从 JavaScript 监听器创建 Dart Stream
如何通过 Dart/Flutter 中的“application/octet-stream”将 png 文件发送到 Microsoft Custom Vision?
Dart - 相当于 Dart 的 C# Stream/MemoryStream 和 stream.WriteByte(..)