Stream 长生不老药:可观察到的

Stream 长生不老药:可观察到的,stream,observablecollection,elixir,Stream,Observablecollection,Elixir,Elixir streams提供了不可测性,但我找不到任何关于可观测的信息(谷歌在这里没有帮助)。如果有人能为我指出同样的资源,我将不胜感激 您可以组合流和枚举来编写可观察的样式代码。下面是一个以可见方式编写的echo服务器示例: IO.stream(:stdio, :line) |> Stream.map(&String.upcase/1) |> Enum.each(&IO.write(&1)) 基本上,对于发送到标准输入的每一行,都将转换为大写,然后打

Elixir streams提供了不可测性,但我找不到任何关于可观测的信息(谷歌在这里没有帮助)。如果有人能为我指出同样的资源,我将不胜感激

您可以组合流和枚举来编写可观察的样式代码。下面是一个以可见方式编写的echo服务器示例:

IO.stream(:stdio, :line) 
|> Stream.map(&String.upcase/1)
|> Enum.each(&IO.write(&1))

基本上,对于发送到标准输入的每一行,都将转换为大写,然后打印回标准输出。这是一个简单的示例,但关键是,您需要合成一个可观察对象的所有内容都已通过Stream和Enum提供。

Elixir中的Streams是对函数合成的抽象。最后,您得到的只是一个函数,调用该函数将在输入流上循环并转换它

为了像Twitter4j中的示例那样构建有状态的流(在一秒钟内缓冲新的twitter法规,并将它们全部发送到一个列表中),您需要使用具有状态的构建块。在Elixir中,在进程中封装状态是很常见的

示例可能如下所示

tweetsPerSecond =
  twitterStream 
  |> SS.buffer({1, :second}) 
  |> SS.map(&length(&1))

SS.subscribe(tweetsPerSecond, fn n -> IO.puts "Got #{n} tweets in the last second" end)
SS.subscribe(tweetsPerSecond, fn n -> IO.puts "Second subscriber" end)
SS
是我们需要编写的新模块,以实现可观察功能。核心思想(据我所知)是能够订阅流而无需修改它

为了实现这一点,
twitterStream
本身应该是一个发送事件供其他人使用的进程。在这种情况下,您不能使用
,因为它具有“阻塞-拉动”语义,即在经过一定时间后,您将无法中断流中下一个元素的等待


要实现Elixir中的等效功能,请查看模块。它提供了发出和订阅事件的能力。不过,据我所知,它没有类似流的接口。

我已经建立了一个酒吧子系统的PoC,我遵循了一种“可观察的模式”:


为了保持状态(必须通知什么流程),我使用了。

请描述您需要解决的问题。也许是其他语言中使用observable的示例?我想为流api构建一个客户端,但不使用回调。类似于“可见物”的东西?Elixir和Erlang都是基于代理的。使用可观察的概念很难比使用基于代理的体系结构做得更多。你的问题类似于站在森林旁边问你在哪里可以找到木材。这篇文章中的对话对于理解长生不老药的不同概念和心态非常有用。它应该是一个公共wiki。为了补充这个响应,使用“可观察样式”的语言可以提供一个在另一个线程中运行的“订阅”方法/函数。在Elixir中,不需要这样的抽象,因为您可以轻松地生成另一个进程,并在另一个进程中生成/使用您的流。例如,您可以简单地在一个新流程中生成上面的代码:
spawn\u link(fn->…code.over…end)
我还应该澄清,由于Observable的推送特性,有两个可观察的操作,例如merge和take\u,直到流不支持为止。然而,Elixir enumerable是可折叠的,并且可以很好地与资源配合使用,因此大部分可观察的功能都在那里。@JoséValim我得到的印象是,OP要求的是一些稍微不同的东西,能够在另一个线程中展开流。请看我的答案。@JoséValim您的第二条评论完美地回答了我的问题。请随意添加它作为答案,我会接受的。