1

我在下面有一个简单的类,它开始然后每秒更新一个计数。我将如何为其添加功能以侦听特定值然后触发回调?

function Counter() {
    this.currentCount = 0;
}

Counter.prototype.start = function() {
    setInterval(this.update, 1000);
};

Counter.prototype.when = function(value, callback) {
    callback(value);
};

Counter.prototype.update = function() {
    this.currentCount++;
};

在我看来,它会像这样工作。

var counter = new Counter();
counter.when(50, function(value) {
    console.log('We arrived at ' + value + ', the requested value.');
});
counter.start();
4

4 回答 4

1

这只是一个很好的作业,我会为你做的;)请看看我的解决方案:

function Counter() {
    this.currentCount = 0;
    this.conditions = [];
    this.interval = undefined;
}

Counter.prototype.start = function() {
    if (!this.interval) {
        var that = this;
        this.interval = setInterval(function () {
            that.update();
        }, 1000);
    }
};

Counter.prototype.stop = function () {
    if (this.interval) {
        clearInterval(this.interval);
        this.interval = undefined;
    }
    this.currentCount = 0;
};

Counter.prototype.when = function(value, callback) {
    var that = this;
    this.conditions.push(function () {
        if (that.currentCount === value) {
            callback.call(that, value);
        }
    });
};

Counter.prototype.update = function() {
    this.currentCount++;
    for (var i = 0, l = this.conditions.length; i < l; i++) {
        var condition = this.conditions[i];
        condition();
    }
};

var counter = new Counter();
counter.when(50, function(value) {
    console.log('We arrived at ' + value + ', the requested value.');
});
counter.when(60, function (value) {
    console.log('Stop at ' + value + '!');
    this.stop();
});
counter.start();

它被摆弄了!

此处的另一个答案在隐藏私有变量方面提出了很好的论据,但实现它有点太混乱了,所以这是另一种类似的方法。这不是共享原型函数,而是使用实例函数。有人可能会说这需要更多内存,但我不认为这很重要,并且允许在真正的构造函数中轻松拥有私有。

var Counter = function () {
    var that = this, currentCount = 0,
        conditions = [], interval;
    var update = function () {
        currentCount++;
        for (var i = 0, l = conditions.length; i < l; i++) {
            var condition = conditions[i];
            condition();
        }
    };
    this.start = function () {
        if (!interval) {
            interval = setInterval(function() {
                update.call(that);
            }, 1000);
        }
    };
    this.when = function (value, callback) {
        conditions.push(function () {
            if (currentCount === value) {
                callback.call(that, value);
            }
        });
    };
    this.stop = function () {
        if (interval) {
            clearInterval(interval);
            interval = undefined;
        }
        currentCount = 0;
    };
};

var counter = new Counter();
counter.when(50, function(value) {
    console.log('We arrived at ' + value + ', the requested value.');
});
counter.when(60, function (value) {
    console.log('Stop at ' + value + '!');
    this.stop();
});
counter.start();

看它摆弄

还要注意,在这两个例子中,counterinstanceof CounterObject
而是和(为什么我喜欢写这么多代码;)Counterinstanceof FunctionObject

于 2013-07-24T00:57:04.020 回答
0

To support multiple whens:

Add an array of whens in your class:

function Counter() {
    this.currentCount = 0;
    this.whens = [];
}

Then let the when function push to that:

Counter.prototype.when = function(value, callback) {
this.whens.push({'time' : value, 'callback' : callback});
}

And check for these whens at update:

Counter.prototype.update = function() {
    this.currentCount++;

    for(var w in this.whens) {
        if(this.currentCount == this.whens[w].time) {
            this.whens[w].callback();
        }
    }
}
于 2013-07-24T00:47:34.283 回答
0

Try something more like:

function Counter(interval, val, func){
  this.currentCount = 0;
  setInterval(function(){
    this.currentCount++;
    if(this.currentCount === val)func();
  }, interval);
}
var nc = new Counter(1000, 50, function(){
  console.log('We have arrived at '+nc.currrentCount);
});
于 2013-07-24T00:50:19.783 回答
0

对于这样的事情有一个论据:

var Counter = (function() {
    var update = function() {
        var idx, callbacks;
        this.currentCount++;
        callbacks = this.callbacks[this.currentCount];
        if (callbacks) {
            for (idx = 0; idx < callbacks.length; idx++) {
                callbacks[idx](this.currentCount);
            }
        }
    };
    var start  = function() {
        var counter = this;
        setInterval(function() {update.call(counter)}, 1000);
    };
    var when = function(count, callback) {
        (this.callbacks[count] || (this.callbacks[count] = [])).push(callback);
    };
    return function() {
        var config = {currentCount: 0, callbacks: {}};
        this.start = function() {return start.call(config);};
        this.when = function(count, callback) {
            return when.call(config, count, callback);
        };
        // this.stop = ... // if desired
    };
}());

这比基于原型的代码版本更占用内存。我不会将它用于您期望数十万或数百万个对象的事情。但它的优点是它真正封装了您可能希望隐藏的数据,例如currentCount回调列表。它不会暴露不必要的update功能。而且它并不比原型版本重得多。每个实例都有自己的startwhen函数,但这些只是常用函数的简单包装。

以同样的方式向它添加一个stop函数有点困难,除非你不介意暴露setInterval. 但这是可行的。

于 2013-07-24T01:52:02.320 回答