我试图在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();
答案 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()
只要排序无关紧要,那么两者都可以。