带有监听器和回调的简单计数器

时间:2013-07-24 00:32:02

标签: javascript callback listener

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

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 个答案:

答案 0 :(得分: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();

并且它是fiddled

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

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();

看到它fiddled

另请注意,在这两个示例中,counter都是instanceof CounterObject
Counterinstanceof FunctionObject(为什么我喜欢写这么多代码;)

答案 1 :(得分:0)

支持多个小时:

在班级中添加一组青少年:

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

然后让when函数推送到:

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

在更新时检查这些人:

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

    for(var w in this.whens) {
        if(this.currentCount == this.whens[w].time) {
            this.whens[w].callback();
        }
    }
}

答案 2 :(得分:0)

尝试更多类似的内容:

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);
});

答案 3 :(得分: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的结果。但它是可行的。