我如何防止事件循环与FRP(和培根.js)

How do I prevent event cycles with FRP (and bacon.js)

本文关键字:js FRP 何防止 事件 循环      更新时间:2023-09-26

我已经成功地在我的培根驱动的应用程序中创建了一个循环,所以我需要一些关于如何打破它的建议。

假设我们有几个属性,它们携带应用程序的某些状态。这种状态应该通过HTML5历史API (pushState)来存储,因此我将这些属性组合到一个对象并对其执行pushState。但是,我还需要覆盖popstate事件,因此在每个popstate(后退按钮等)上,我将状态对象拆分为单个属性并将它们注入其原始流。

现在我有了一个循环:因为这些属性流是我首先得到pushState的相同流,pushState再次被调用,复制堆栈上的状态,使后退按钮无用。

这当然是我的错误,然而,除了将每个属性流分成两个并在pushState/popState特定的情况下以不同的方式组合它们之外,我没有看到一个好的解决方案。但这似乎相当不优雅——有没有什么规范的方法来避免这种循环?

我想到的最优雅的解决方案是在推送新状态之前检查当前状态。如果它们是相同的,什么都不做:

// state properties
var foo = ...;
var bar = ...;
// write
var history = Bacon.combineAll(makeHistoryState, foo, bar);
history.onValue(function (v) {
    if (!_.isEqual(history.state, v)) {
        history.pushState(v);
    }
});
// read
window.addEventListener("popstate", function(event.state) {
    foo.set(extractFoo(event.state));
    bar.set(extractBar(event.state));
});

免责声明:我没有自己测试

编辑:当拥有全局状态作为单个属性时,它被保存到历史API中;一切simplfies。你可以利用培根。模型镜头功能