【问题标题】:Bacon.js EventStream from valueBacon.js EventStream 来自值
【发布时间】:2016-07-03 16:57:55
【问题描述】:

假设我的代码中有一个任意值: var 任意值 = null;

我的代码中有多个地方可以更改此值。我可以创建一个基于 this 值变化的 EventStream 吗?也就是说,如果更改了任意值,新的值会作为 EventStream 发送给订阅者吗?

【问题讨论】:

  • 你应该使用Bus

标签: javascript bacon.js


【解决方案1】:

使用Bus 而不是普通值:

var arbitraryValueBus = Bacon.Bus()

现在您可以使用Bus.push 设置值:

arbitraryValueBus.push(newValue)

您可以通过订阅Bus来收听值的变化:

arbitraryValueBus.forEach(newValue => console.log(newValue))

请注意,使用简单的Bus,您的订阅者将不会获得在调用forEach 之前设置的值。所以,如果你想添加一个“当前值”,并立即使用当前值调用你的回调,你应该使用Property

var b = Bacon.Bus()
var p = arbitraryValueBus.toProperty()
p.forEach() // to make sure it's updated before adding subscribers
b.push("first value")
p.subscribe(x => console.log(x))

==> outputs "first value"

现在您的订阅者将立即获得当前值(如果有的话)。

【讨论】:

    【解决方案2】:

    感谢您的回答!也许 Bacon.js 不是我想要的,所以我决定创建自己的“反应式编程”库。它会立即计算新值,而无需使用 setTimeout 检查值。

    var = createReactiveValue = function(initialValue) {
    return {
        "observers": [], // Call these functions with a new value when it has been set
        "value":initialValue,
        "set": function(newValue) {
            this.value = newValue;
    
            this.observers.forEach(function(observer) {
                // Call observers asynchronously
                setTimeout(function() { observer(this.value) }, 0);
            })
        },
        "get": function() {
            return this.value;
        },
        "addObserver": function(observer) {
            this.observers.push(observer);
        }
    };
    };
    
    // If any of the dependant values change, sets reactive value 'value' to the result of calling 'result'
    var = makeReaction = function(value, dependencies, result) {
        // Start watching changes in dependencies
        dependencies.forEach(function(dependency) {
            dependency.addObserver(function(newValue) {
                var newResult = result(value, dependencies);
                value.set(newResult);
            });
        });
    };
    
    
    // When 'reactiveValue' is changed, calls the given 'result' function with the new value
    var = watchReaction = function(reactiveValue, result) {
        // Start watching changes in reactive value
        reactiveValue.addObserver(function(newValue) {
            result(newValue);
        });
    };
    
    var a = createReactiveValue(2);
    var b = createReactiveValue(1);
    var c = createReactiveValue(null);
    
    // We want c to depend on both a and b. If either a or b change, c should    automatically recalculate it's value
    makeReaction(c, [a, b], function(c, [a, b]) {
        return a.get() + b.get();
    });
    
    // If c is changed, for whatever reason, log it
    watchReaction(c, function(newC) {
        console.log("Reaction completed: " + a.get() + " + " + b.get() + " = " + c.get());
    });
    
    // Test it by resetting value a to random
    setInterval(function()
    {
        var newValue = Math.random();
        a.set(newValue); },
    1000); // Logs the new result imm
    

    编辑:现在作为库提供:https://github.com/Jarzka/ReaktioJS

    【讨论】:

      【解决方案3】:

      检查值是否改变

      在 js 中检查变量的值是否变化并不难。

      function checkValue() {
          var newValue = value;
          if (newValue != value) {
              // Value has changed
              // .... (Code that needs to be executed)
          }
      }
      

      通过阅读您的问题,我得出结论,您需要经常检查值是否发生变化。为此,我建议使用以下功能:

      function checkValue(interval) {
          var checkInterval = setInterval(function () {
              var newValue = value;
              if (newValue != value) {
                  // Value has changed
                  // .... (Code that needs to be executed)
              }
          }, interval); 
      }
      

      在代码开头的某处调用此函数将检查您的值是否每interval 毫秒更改一次。要停止此过程,您需要做的就是清除间隔。请注意,我已将区间放在变量中,以使清除区间成为可能。

      清除间隔就像这样简单:

      clearInterval(checkInterval);
      

      注意:请设置间隔,使其每隔一秒左右检查一次。 (1000 毫秒)。它可能不需要低于此值,并且更频繁地检查只是给浏览器带来了不必要的工作。

      我希望这能回答你的问题!

      【讨论】:

      • 顺便说一句,我对 bacon.js 不熟悉,所以你需要的任何“将值作为 eventString 发送给订阅者”的代码都必须来自其他人,我希望我'已经回答了你的问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-15
      • 1970-01-01
      • 2014-11-03
      • 1970-01-01
      • 1970-01-01
      • 2014-09-17
      相关资源
      最近更新 更多