如何将javascript函数存储在队列中以便最终执行
我已经用javascript创建了一个队列类,我想将函数作为数据存储在队列中。这样我就可以建立请求(函数调用)并在需要时响应它们(实际执行函数) 是否有任何方法将函数存储为数据,有点类似于如何将javascript函数存储在队列中以便最终执行,javascript,function,timeout,queue,Javascript,Function,Timeout,Queue,我已经用javascript创建了一个队列类,我想将函数作为数据存储在队列中。这样我就可以建立请求(函数调用)并在需要时响应它们(实际执行函数) 是否有任何方法将函数存储为数据,有点类似于 .setTimeout("doSomething()", 1000); 除非是 functionQueue.enqueue(doSomething()); 它将doSomething()存储为数据,因此当我从队列中检索数据时,将执行该函数 我猜我必须在引号中加上doSomething()->“doSome
.setTimeout("doSomething()", 1000);
除非是
functionQueue.enqueue(doSomething());
它将doSomething()存储为数据,因此当我从队列中检索数据时,将执行该函数
我猜我必须在引号中加上doSomething()->“doSomething()”以及一些如何让它使用字符串调用函数的方法,有人知道如何做到这一点吗?指的是您正在存储的函数,末尾没有()
doSomething
是一个变量(恰好是一个函数)doSomething()
是执行函数的指令
稍后,当您使用队列时,您将需要类似于
(functionQueue.pop())()
——即执行functionQueue.pop,然后执行对pop的调用的返回值。您还可以使用函数对象的.call()方法
function doSomething() {
alert('doSomething');
}
var funcs = new Array();
funcs['doSomething'] = doSomething;
funcs['doSomething'].call();
此外,还可以将函数直接添加到队列:
funcs['somethingElse'] = function() {
alert('somethingElse');
};
funcs['somethingElse'].call();
所有函数实际上都是变量,因此实际上很容易将所有函数存储在数组中(通过引用它们而不使用
()
):
如果您想将参数传递给函数,那么这会变得有点复杂,但是一旦您设置了执行此操作的框架,以后每次都会变得容易。本质上,您要做的是创建一个包装函数,当调用该函数时,它将触发一个具有特定上下文和参数集的预定义函数:
// Function wrapping code.
// fn - reference to function.
// context - what you want "this" to be.
// params - array of parameters to pass to function.
var wrapFunction = function(fn, context, params) {
return function() {
fn.apply(context, params);
};
}
现在我们有了一个用于包装的实用函数,让我们看看如何使用它来创建未来的函数调用:
// Create my function to be wrapped
var sayStuff = function(str) {
alert(str);
}
// Wrap the function. Make sure that the params are an array.
var fun1 = wrapFunction(sayStuff, this, ["Hello, world!"]);
var fun2 = wrapFunction(sayStuff, this, ["Goodbye, cruel world!"]);
// Create an array and append your functions to them
var funqueue = [];
funqueue.push(fun1);
funqueue.push(fun2);
// Remove and execute all items in the array
while (funqueue.length > 0) {
(funqueue.shift())();
}
这段代码可以通过允许包装器使用数组或一系列参数来改进(但这样做会弄乱我试图制作的示例)
标准答案张贴
下面是一个很好的队列类,您可以使用而不使用超时:
var Queue = (function(){
function Queue() {};
Queue.prototype.running = false;
Queue.prototype.queue = [];
Queue.prototype.add_function = function(callback) {
var _this = this;
//add callback to the queue
this.queue.push(function(){
var finished = callback();
if(typeof finished === "undefined" || finished) {
// if callback returns `false`, then you have to
// call `next` somewhere in the callback
_this.next();
}
});
if(!this.running) {
// if nothing is running, then start the engines!
this.next();
}
return this; // for chaining fun!
}
Queue.prototype.next = function(){
this.running = false;
//get the first element off the queue
var shift = this.queue.shift();
if(shift) {
this.running = true;
shift();
}
}
return Queue;
})();
它可以这样使用:
var queue = new Queue;
queue.add_function(function(){
//start running something
});
queue.add_function(function(){
//start running something 2
});
queue.add_function(function(){
//start running something 3
});
我自己也做过很多,但从未想过同时存储上下文和参数。非常好。它如何与ajax请求之类的同步方法一起工作?我如何链接ajax方法?函数不是变量,而是对象。不过很有帮助的帖子!谢谢谢谢,当页面顶部的元素在视口上方滚动时,我一直在努力平滑地删除它们。iOS 8让这变得很困难,你的速度检测挽救了这一天!如果您想捕获从内部函数返回的结果,请使用以下命令:
return fn.apply(context,params)代码>在许多情况下不使用setTimeout是可以的。设置setTimeout当然有助于将执行返回到Javascript任务队列
/事件循环
。通过这种冗长的代码部分将不会阻止浏览器。
var queue = new Queue;
queue.add_function(function(){
//start running something
});
queue.add_function(function(){
//start running something 2
});
queue.add_function(function(){
//start running something 3
});