考虑使用 zip运算符将两个无限的 Observable 压缩在一起,其中一个发出的数据项的频率是另一个的两倍。
当前的实现是无损的,即如果我让这些 Observable 发射一个小时,然后我在它们的发射率之间切换,第一个 Observable 最终会 catch 另一个。
随着缓冲区变得越来越大,这会在某个时候导致内存爆炸。
如果第一个 observable 将在几个小时内发出项目,而第二个将在最后发出一个项目,则会发生同样的情况。
如何实现此运算符的有损行为?我只想在我从两个流中获得排放时进行排放,我不在乎我错过了更快的流中有多少排放。
说明:
zip 运算符的无损特性导致的内存爆炸。示例:
Stream1: 1 2 3 4 5 6 7
Stream2: 10 20 30 40 50 60 70
常规 zip 将产生以下输出:
[1, 10]
[2, 20]
[3, 30]
[4, 40]
[5, 50]
[6, 60]
[7, 70]
const Observable = Rx.Observable;
const Subject = Rx.Subject;
const s1 = new Subject();
const s2 = new Subject();
Observable.zip(s1,s2).subscribe(console.log);
s1.next(1); s1.next(2); s2.next(10); s1.next(3); s1.next(4); s2.next(20); s1.next(5); s1.next(6); s1.next(7); s2.next(30);
s2.next(40); s2.next(50); s2.next(60); s2.next(70); <script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>
我希望它产生的输出:
[1, 10]
[3, 20]
[5, 30]
解释:
有损 zip 运算符是缓冲区大小为 1 的 zip。这意味着它只会保留第一个发出的流中的第一个项目,并会丢失所有其余的(在第一个项目和第二个流的第一个发射之间到达的项目)。所以示例中发生的情况如下:stream1 发出 1,有损 zip“记住”它并忽略 stream1 上的所有项目,直到 stream2 发出。 stream2 的首次发射是 10,因此 stream1 丢失 2。在相互发射(有损 zip 的第一次发射)之后,它重新开始:“记住”3,“松散”4,发射 [3,20]。然后重新开始:“记住”5,“松散”6 和 7,发出 [5,30] .然后重新开始:“记住”40,“松散”50,60,70,等待下一个stream1 上的项目。
示例 2:
Stream1: 1 2 3 ... 100000000000
Stream2: a
在这种情况下,常规的 zip 运算符会占用内存。
我不想这样。
总结:
本质上,我希望有损 zip 运算符只记住 stream 1 发出的第一个值 after previous mutual emission 并在 stream 2 时发出 catch stream 1。并重复。
最佳答案
以下将为您提供所需的行为:
Observable.zip(s1.take(1), s2.take(1)).repeat()
在 RxJs 5.5+ 管道语法中:
zip(s1.pipe(take(1)), s2.pipe(take(1))).pipe(repeat());
const s1 = new Rx.Subject();
const s2 = new Rx.Subject();
Rx.Observable.zip(s1.take(1), s2.take(1)).repeat()
.subscribe(console.log);
s1.next(1); s1.next(2); s2.next(10); s1.next(3); s1.next(4); s2.next(20); s1.next(5); s1.next(6); s1.next(7); s2.next(30);
s2.next(40); s2.next(50); s2.next(60); s2.next(70); <script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>
解释:
repeat 运算符(在其当前实现中)在后者完成后重新订阅可观察到的源,即在这种特殊情况下,它会在每次相互发射时重新订阅 zip。zip 组合两个 observable 并等待它们发出。 combineLatest 也可以,这并不重要,因为 take(1)take(1) 实际上负责内存爆炸并定义有损行为如果你想在相互发射时从每个流中获取最后一个而不是第一个值,使用这个:
Observable.combineLatest(s1, s2).take(1).repeat()
在 RxJs 5.5+ 管道语法中:
combineLatest(s1.pipe(take(1)), s2.pipe(take(1))).pipe(repeat());
const s1 = new Rx.Subject();
const s2 = new Rx.Subject();
Rx.Observable.combineLatest(s1,s2).take(1).repeat()
.subscribe(console.log);
s1.next(1); s1.next(2); s2.next(10); s1.next(3); s1.next(4); s2.next(20); s1.next(5); s1.next(6); s1.next(7); s2.next(30);
s2.next(40); s2.next(50); s2.next(60); s2.next(70); <script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>
关于javascript - RxJs:zip 运算符的有损形式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46602541/
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
请帮助我理解范围运算符...和..之间的区别,作为Ruby中使用的“触发器”。这是PragmaticProgrammersguidetoRuby中的一个示例:a=(11..20).collect{|i|(i%4==0)..(i%3==0)?i:nil}返回:[nil,12,nil,nil,nil,16,17,18,nil,20]还有:a=(11..20).collect{|i|(i%4==0)...(i%3==0)?i:nil}返回:[nil,12,13,14,15,16,17,18,nil,20] 最佳答案 触发器(又名f/f)是
我有一个名为posts的模型,它有很多附件。附件模型使用回形针。我制作了一个用于创建附件的独立模型,效果很好,这是此处说明的View(https://github.com/thoughtbot/paperclip):@attachment,:html=>{:multipart=>true}do|form|%>posts中的嵌套表单如下所示:prohibitedthispostfrombeingsaved:@attachment,:html=>{:multipart=>true}do|at_form|%>附件记录已创建,但它是空的。文件未上传。同时,帖子已成功创建...有什么想法吗?
我明白了:x,(y,z)=1,*[2,3]x#=>1y#=>2z#=>nil我想知道为什么z的值为nil。 最佳答案 x,(y,z)=1,*[2,3]右侧的splat*是内联扩展的,所以它等同于:x,(y,z)=1,2,3左边带括号的列表被视为嵌套赋值,所以它等价于:x=1y,z=23被丢弃,而z被分配给nil。 关于ruby-带括号和splat运算符的并行赋值,我们在StackOverflow上找到一个类似的问题: https://stackoverflow
我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的
问题是:除了在“OperatorExpressions”?例如:1%!2 最佳答案 是的,可以创建自定义运算符,但有一些注意事项。Ruby本身并不直接支持它,但是superatorsgem做了一个巧妙的把戏,将运算符链接在一起。这允许您创建自己的运算符,但有一些限制:$geminstallsuperators19然后:require'superators19'classArraysuperator"%~"do|operand|"#{self}percent-tilde#{operand}"endendputs[1]%~[2]#Out
我有一个类unzipper.rb,它使用Rubyzip解压文件。在我的本地环境中,我可以成功解压缩文件,而无需使用require'zip'明确包含依赖项但是在Heroku上,我得到一个NameError(uninitializedconstantUnzipper::Zip)我只能通过使用明确的require来解决问题:为什么这在Heroku环境中是必需的,但在本地主机上却不是?我的印象是Rails自动需要所有gem。app/services/unzipper.rbrequire'zip'#OnlyrequiredforHeroku.Workslocallywithout!class
在Ruby中有运算符(operator)。在API中,他们没有命名它的名字,只是:Theclassmustdefinetheoperator...Comparableusestoimplementtheconventionalcomparison......theobjectsinthecollectionmustalsoimplementameaningfuloperator...它叫什么名字? 最佳答案 参见上面的@Tony。然而,它也被称为(俚语)“宇宙飞船运算符(operator)”。
也许这听起来很荒谬,但我想知道这对Ruby是否可行?基本上我有一个功能...defadda,bc=a+breturncend我希望能够将“+”或其他运算符(例如“-”)传递给函数,这样它就类似于...defsuma,b,operatorc=aoperatorbreturncend这可能吗? 最佳答案 两种可能性:以方法/算子名作为符号:defsuma,b,operatora.send(operator,b)endsum42,23,:+或者更通用的解决方案:采取一个block:defsuma,byielda,bendsum42,23,
可能真的很简单,但我很难在网上找到关于这个的文档我在Ruby中有两个activerecord查询,我想通过OR运算符连接在一起@pro=Project.where(:manager_user_id=>current_user.id)@proa=Project.where(:account_manager=>current_user.id)我是ruby的新手,但我自己尝试使用||@pro=Project.where(:manager_user_id=>current_user.id||:account_manager=>current_user.id)这没有用,所以1.我想知道如何在