如何将JavaScript函数存储在队列中以便最终执行它们
我已经在JavaScript中创build了一个Queue类,我想将函数作为数据存储在队列中。 这样我可以build立请求(函数调用),并在需要时(实际执行该函数)响应它们。
有没有什么办法把函数作为数据存储,有点类似于
.setTimeout("doSomething()", 1000);
除非是这样
functionQueue.enqueue(doSomething());
在那里它会存储doSomething()作为数据,所以当我从队列中检索数据时,函数将被执行。
我猜我必须有doSomething()在引号 – >“doSomething()”和一些如何使用string调用函数,任何人都知道如何做到这一点?
所有的函数实际上都是variables,因此将所有函数存储在数组中实际上非常简单(通过引用它们而不使用()
):
// Create your functions, in a variety of manners... // (The second method is preferable, but I show the first for reference.) function fun1() { alert("Message 1"); }; var fun2 = function() { alert("Message 2"); }; // Create an array and append your functions to them var funqueue = []; funqueue.push(fun1); funqueue.push(fun2); // Remove and execute the first function on the queue (funqueue.shift())();
如果你想传递参数给你的函数,这会变得更复杂一些,但是一旦你设置了这个框架,一旦这个框架变得容易,那么每一次都变得容易。 基本上你要做的就是创build一个包装函数,当被调用时,它会使用特定的上下文和参数集来触发一个预定义的函数:
// 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); }; }
现在我们已经有了一个用于包装的实用函数,让我们看看它是如何被用来创build未来的函数调用的:
// 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())(); }
这个代码可以通过允许包装器使用一个数组或一系列参数来改进(但是这样做会混淆我试图做的例子)。
标准答案发布在这里
这是一个很好的Queue类,你可以使用而不使用超时:
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 });
请参阅最后没有使用()的存储function。 doSomething
是一个variables(恰好是一个函数); doSomething()
是执行该函数的指令。
之后,当你使用队列的时候,你需要像(functionQueue.pop())()
这样的函数,也就是执行functionQueue.pop,然后执行那个调用的返回值来popup。
您也可以使用函数对象的.call()方法。
function doSomething() { alert('doSomething'); } var funcs = new Array(); funcs['doSomething'] = doSomething; funcs['doSomething'].call();
另外,你也可以直接将函数添加到队列中:
funcs['somethingElse'] = function() { alert('somethingElse'); }; funcs['somethingElse'].call();