繁体   English   中英

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

[英]setInterval in member function of object error

我正在尝试在nodeJS模块中创建各种限制队列。 我收到此错误:

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

我猜想我像往常一样做着愚蠢的事情,但是是否有原因导致第二个间隔运行时它失去了关闭范围或其他东西呢?

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

这行看起来非常可疑:

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

runQueue不返回任何函数,实际上它什么也不返回( undefined )。 您可能想要:

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

这是一个非常常见的错误。 您正在立即运行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)

为了补充现有的答案, 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();

这正是我在寻找的东西,谢谢。

唯一的问题:您实现了堆栈,而不是队列。

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

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

只要顺序无关紧要,那么都可以。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM