将多个淘汰订阅整理到一个通知中?

时间:2014-12-03 13:59:00

标签: javascript knockout.js observable

在淘汰赛中,您可以执行以下操作:

myObservable.subscribe(function(newValue){ doSomething(); });

现在,如果我想要订阅多个observable,我可以这样做:

myObservable1.subscribe(function(){ doSomething(); }); myObservable2.subscribe(function(){ doSomething(); });

然而,当我有大量订阅时,这可能会有点不雅观,如果你想要限制更新机制,你现在必须按订阅进行。

那么我有办法以某种方式包装它们吗?即。

ko.subscribeToMany(myObservable1, myObservable2) .throttle(500) .subscribe(function(){ doSomething() });

我有一个场景,我基本上想要根据更改刷新图表,而且资源非常密集,所以我希望不必订阅每个动态位数据,我可以将它们整理成单个计算样式订阅,然后从那里节流个人订阅,因为其他订阅可能希望立即通知没有延迟/节流。

Knockout可以实现上述目标吗?

1 个答案:

答案 0 :(得分:2)

快速实施可能如下:

ko.obsgroup = function() {

    var groupManager = {};    
    var observables = [];

    var throttle = 0;
    var throttleTimeout;

    for(var i = 0; i < arguments.length; i++) {
        observables.push(arguments[i]);
    }

    groupManager.throttle = function(duration) {
        throttle = duration;
        return groupManager;
    };

    groupManager.subscribe = function(handler) {

        function throttledHandler(val) {
            if(throttle > 0) {
                if(!throttleTimeout) {
                    throttleTimeout = setTimeout(function() {
                        throttleTimeout = undefined;
                        handler(val);
                    }, throttle);
                }
            } else {
                handler(val);
            }
        }

        for(var i = 0; i < arguments.length; i++) {
            observables[i].subscribe(throttledHandler);
        }
        return groupManager;
    };

    return groupManager;
};

用法:

var vm = {
    v1: ko.observable(0),
    v2: ko.observable(0),
    v3: ko.observable(0),
    log: ko.observable(0)
};

ko.obsgroup(vm.v1, vm.v2, vm.v3)
  .throttle(1000)
  .subscribe(function(val) {
      vm.log('changed: ' + Date.now());
  });

ko.applyBindings(vm);

演示:JSFiddle