【发布时间】:2018-08-14 20:39:31
【问题描述】:
我正在尝试使用 Rx(Js) 学习反应式编程,同时制作一个小 cookieclicker 风格的游戏。我想弄清楚 Rx 是否合适,所以我试图将游戏事件建模为流。
首先,有收入流,这对 RxJs 来说非常好:
const click$ = fromEvent($("#clicker"), "click")
const autoclick$ = interval(1000)
const earnedGold$ = merge(click$, autoclick$)
.map(() => 10)
.scan((acc, next) => next + acc, 0)
这样earnedGold$ 会为每次鼠标点击和每次自动点击发出总获得的金币(每次点击 10)。我可以添加更多可用的黄金来源。
问题是:如何实施支出?
我有另一个流,purchaseOrders$,它由几个不同的按钮点击组成,并发出如下对象:{ price: 150, upgrade: { type: "speed", amount: 15 } }
ISTM 我现在想将此流转换为两个:spentGold$ 用于价格,purchases$ 用于实际购买的升级。当然,只有当你有足够的金币时,你才能购买东西。
我如何获得当前的黄金总数?我最初打算有一个currentGold$ 流,它将earnedGold$ 与spentGold$ 合并并发出运行总数。但事实证明,我需要这个currentGold$ 作为决定是否首先发出购买的输入?
我可以通过将spentGold$ 变成Subject 来解决这种循环依赖关系,但是a) 似乎不是反应方式,并且b) 打开了一个竞争条件,见下文。
另一种方法是保留一个简单的currentGold 变量并将其从订阅者更新到支出/收入流。然后在决定是否允许购买时,我可以检查这个变量,发出购买和升级。
但是,与Subject 解决方案一样,这会打开一个竞争条件:我怎么知道currentTotal 是最新的WRT 排队花费?如果我发出采购订单并且订阅者在我到达下一个排队的采购订单之前没有更新总计,我仍将使用旧的总计。
当然,我可以在发出购买之前从总数中减去,但是当有更多失去金币的方式时,这可能会打开更多的比赛条件。
首先我也不能允许不确定的“采购订单”;如果总数不够高,“购买”按钮将被禁用。但这似乎也容易受到竞争条件的影响。
那么,有什么好的解决方案呢?
【问题讨论】:
标签: javascript rxjs reactive-programming