【发布时间】:2016-02-07 15:26:51
【问题描述】:
我正在玩响应式编程,使用 RxJS,但偶然发现了一些我不知道如何解决的问题。
假设我们实现了一台自动售货机。你投入一枚硬币,选择一个物品,机器会分发一个物品并返回找零。我们假设价格始终为 1 美分,因此插入四分之一(25 美分)应返回 24 美分,依此类推。
“棘手”的部分是我希望能够处理用户插入 2 个硬币然后选择一个项目这样的情况。或者选择一个项目而不插入硬币。
将插入的硬币和选定的项目实现为流似乎很自然。然后我们可以在这两个动作之间引入某种依赖关系——合并或压缩或合并最新的。
但是,我很快遇到了一个问题,我希望将硬币累积到分发物品之前,而不是进一步。 AFAIU,这意味着我不能使用sum 或scan,因为在某个时候无法“重置”之前的累积。
这是一个示例图:
coins: ---25---5-----10------------|->
acc: ---25---30----40------------|->
items: ------------foo-----bar-----|->
combined: ---------30,foo--40,bar--|->
change:------------29------39------|->
以及对应的代码:
this.getCoinsStream()
.scan(function(sum, current) { return sum + current })
.combineLatest(this.getSelectedItemsStream())
.subscribe(function(cents, item) {
dispenseItem(item);
dispenseChange(cents - 1);
});
插入 25 和 5 美分,然后选择“foo”项目。累积硬币然后组合最新的将导致“foo”与“30”(这是正确的)组合,然后是“bar”与“40”(不正确;应该是“bar”和“10”)。
我查看了all of the methods 进行分组和过滤,但没有看到任何我可以使用的东西。
我可以使用的另一种解决方案是分别积累硬币。但这会在流之外引入状态,我真的很想避免这种情况:
var centsDeposited = 0;
this.getCoinsStream().subscribe(function(cents) {
return centsDeposited += cents;
});
this.getSelectedItemsStream().subscribe(function(item) {
dispenseItem(item);
dispenseChange(centsDeposited - 1);
centsDeposited = 0;
});
此外,这不允许使流相互依赖,例如等待硬币被插入,直到选定的操作可以返回一个项目。
我是否缺少已经存在的方法?实现这样的事情的最佳方法是什么 - 累积值直到它们需要与另一个流合并的那一刻,但还要等待第一个流中的至少一个值,然后再将其与第二个流中的值合并?
【问题讨论】:
-
我不确定,但你可以看看jsbin.com/vimito/edit?js,console
-
很抱歉打扰您,但请您看看stackoverflow.com/questions/44434944。任何帮助将不胜感激。
标签: javascript asynchronous reactive-programming rxjs