setInterval在对象错误的成员函数中

时间:2015-04-25 18:52:01

标签: javascript node.js

我试图在nodeJS模块中创建各种类型的限制队列。我收到了这个错误:

timers.js:265     callback.apply(this,args);             ^ TypeError:无法读取属性' apply'未定义的     在包装器[as _onTimeout](timers.js:265:13)     在Timer.listOnTimeout(timers.js:110:15)

我猜测我像往常一样做了一些愚蠢的事情,但是当第二个间隔运行时,是否有理由失去关闭范围?

   var queueSvc = function(settings){
    var queue = ['bob', 'is', 'name', 'my', 'hi'];
    var svc = {};

    var runtime;

    svc.addQuery = function(queueEntry){
        queue.push(queueEntry);
    };

    svc.stopQueue = function(){
        clearInterval(runtime);
    };

    svc.startQueue = function(){
        runtime = setInterval(runQueue(queue), settings.queueInterval);
    };

    svc.emptyQueue = function(){
        //This method of emptying the array needs to change
        //if we decide to make the queue a public property
        queue = [];
    };

    return svc; 
};

function runQueue(queue){
    console.log(JSON.stringify(queue));
    if(queue.length > 0){
        var entry = queue.pop();
        console.log(entry);
    }
}

var it = queueSvc({queueInterval: 3000});

it.startQueue();

4 个答案:

答案 0 :(得分:2)

这条线看起来非常可疑:

setInterval(runQueue(queue), settings.queueInterval);

runQueue不返回函数,实际上它不返回任何内容(undefined)。你可能想要:

setInterval(function () {
    runQueue(queue);
}, settings.queueInterval);

答案 1 :(得分:2)

这是一个非常常见的错误。您正在立即运行runQueue(queue),然后将其返回值传递给setInterval()。返回值为undefined,所以你所做的基本上是这样的:

runQueue(queue);
setInterval(undefined, settings.queueInterval);

这显然不是你想要的。每当你将()放在runQueue()之后的函数之后,意味着立即运行它。在没有()的函数名称或定义之后,它只是传递一个稍后可以调用的函数引用。

所以,你需要传递一个函数引用setInterval(),可以像这样调用LATER:

setInterval(function() {
    runQueue(queue);
}, settings.queueInteval);

当你将它分解为一个命名函数时,人们有时会更好地理解它(不是必需的,但有助于理解正在发生的事情):

function run() {
    runQueue(queue);
}

setInterval(run, settings.queueInteval);

在这里,您看到只传递了setInterval()的函数引用,并让计时器基础结构稍后调用该函数。

我的第一个代码块中的匿名函数完成了同样的事情。它声明了第二个函数,我们可以将引用传递给setInterval(),当调用它时,它会使用所需的参数调用runQueue(queue)

答案 2 :(得分:0)

要补充现有答案,请将runQueue包装成可调用的内容。但是,您也可以完全重构逻辑。

var queueSvc = function(settings){
    var queue = ['bob', 'is', 'name', 'my', 'hi'];
    var svc = {};

    var runtime;

    svc.addQuery = function(queueEntry){
        queue.push(queueEntry);
    };

    svc.stopQueue = function(){
        clearInterval(runtime);
    };

    svc.startQueue = function(){
        runtime = setInterval(svc.runQueue, settings.queueInterval);
    };

    svc.emptyQueue = function(){
        //This method of emptying the array needs to change
        //if we decide to make the queue a public property
        queue = [];
    };

    svc.runQueue = function() {
        console.log(JSON.stringify(queue));
        if(queue.length > 0){
            var entry = queue.pop();
            console.log(entry);
        }
    };

    return svc; 
};

var it = queueSvc({queueInterval: 3000});

it.startQueue();

答案 3 :(得分:0)

这正是我所寻找的,谢谢。

只有一个问题:您实现了堆栈,而不是队列。

队列是FIFO并使用push()和shift()

堆栈是LIFO并使用push()和pop()

只要排序无关紧要,那么两者都可以。