淘汰赛可观察到多个订阅

时间:2019-05-29 14:44:54

标签: javascript knockout.js observable subscribe

我继承了一个使用Knockout编写的UI应用程序,我很好奇对于单个可观察属性进行多个订阅会有什么影响?

我有一个观察站,有2个订阅。通过登录到控制台,我可以看到两个订阅都被触发,一个接一个。

使用下面的示例:(为简洁起见,为简洁起见,这里有很多逻辑,其中有些是重复的)

self.VisitDate = ko.observable();

self.VisitDate.subscribe(function (newValue) {
    self.ListItemRemoved(removed);
});   

self.VisitDate.subscribe(function (newValue) {
    self.Basket.VisitDate(newValue);
});

我原本以为我应该看到某种错误,因为有多个订阅,但是一切似乎都正常,但是我找不到任何清楚的解释为什么可以这样做?

我只是想找出以下内容:

对一个可观察的对象进行多个订阅是否正常并且可以接受? 这样做是否对比赛有潜在的影响? 是否真的需要多个订阅才能实现单个订阅中无法实现的功能?

我很高兴在细节上有些害羞,但是我实际上只是想了解敲除的幕后工作方式,以了解我是否应该重构该代码。

1 个答案:

答案 0 :(得分:0)

observer/observable design pattern确实允许多个观察者/订阅。简而言之,设计模式的目的是:

  1. 将变更与变更的影响脱钩。
  2. 允许更改产生任何任意影响。

因此,淘汰赛是通过可观察的方式做到的。

var observable = ko.observable("a");

observable.subscribe(function(newValue) {
  console.log("observer 1", newValue)
});

observable.subscribe(function(newValue) {
  console.log("observer 2", newValue)
});

observable.subscribe(function(newValue) {
  console.log("observer 3", newValue)
});

observable("b");
observable("c");
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

由于your code will be run in a single thread,没有真正要担心的比赛条件,因此,除非您明确选择加入某种multi-threadedness,否则它肯定可以确定。

通常,观察者通常也不会固有地调用多个线程,因为订阅者更新功能通常采用以下形式:

for (subscriber of this.subscribers) {
  subscriber.update(this.value);
}

这样说,您可能会遇到问题,但前提是订户依赖于共享状态,并且您不能保证或知道每个订户的添加顺序。在这种情况下,您可以根据订阅顺序获得不同的结果。简单演示:

var observable = ko.observable("a");

var sharedState = "";

observable.subscribe(function(newValue) {
  //append to the shared state
  sharedState += newValue;
  console.log("observer 1", sharedState);
});

observable.subscribe(function(newValue) {
  //double up the shared state
  sharedState += sharedState;
  console.log("observer 2", sharedState);
});

observable("b");
observable("c");
observable("d");
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

var observable = ko.observable("a");

var sharedState = "";


observable.subscribe(function(newValue) {
  //double up the shared state
  sharedState += sharedState;
  console.log("observer 2", sharedState);
});

observable.subscribe(function(newValue) {
  //append to the shared state
  sharedState += newValue;
  console.log("observer 1", sharedState);
});

observable("b");
observable("c");
observable("d");
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

因此,这将是一个不好的做法。如果可能的话,最好避免。除非您可以保证订阅的顺序-在上面的示例中,我将一个接一个地添加订阅,以确保订阅以添加顺序显示。但是您可能拥有可以有条件地或在应用程序的不同部分添加订阅的代码,在这种情况下,很难控制该顺序。