如何将javascript函数存储在队列中以便最终执行它们

72 javascript queue timeout function

我在javascript中创建了一个Queue类,我希望将函数存储为队列中的数据.这样我就可以构建请求(函数调用)并在需要时(实际执行函数)响应它们.

有没有办法将函数存储为数据,有点类似于

.setTimeout("doSomething()", 1000);
Run Code Online (Sandbox Code Playgroud)

除了它会

functionQueue.enqueue(doSomething());
Run Code Online (Sandbox Code Playgroud)

它将doSomething()存储为数据,因此当我从队列中检索数据时,将执行该函数.

我猜我必须在引号中使用doSomething() - >"doSomething()"以及如何使用字符串调用函数,任何人都知道如何做到这一点?

Dan*_*Lew 183

所有函数实际上都是变量,因此实际上很容易将所有函数存储在数组中(通过引用它们而不是()):

// 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())();
Run Code Online (Sandbox Code Playgroud)

如果你想将参数传递给你的函数,这会变得有点复杂,但是一旦你设置了这个框架,一旦它变得容易,每次都变得容易.基本上你要做的是创建一个包装函数,当被调用时,它会触发一个具有特定上下文和参数集的预定义函数:

// 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);
    };
}
Run Code Online (Sandbox Code Playgroud)

现在我们已经有了一个包装的实用程序函数,让我们看看它是如何用来创建函数的未来调用的:

// 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())();   
}
Run Code Online (Sandbox Code Playgroud)

这个代码可以通过允许包装器使用数组或一系列参数来改进(但这样做会混淆我试图制作的例子).

  • 它如何工作宽度assync方法,如ajax请求,我如何链接ajax方法? (3认同)
  • 函数不是它们作为对象的变量.不过很有帮助的帖子!谢谢! (2认同)

Nea*_*eal 25

Canonical的答案贴在这里


这是一个很好的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;

})();
Run Code Online (Sandbox Code Playgroud)

它可以像这样使用:

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
});
Run Code Online (Sandbox Code Playgroud)


Dan*_*ett 6

请参阅最后没有()的情况下存储的功能. doSomething是一个变量(恰好是一个函数); doSomething()是执行该功能的指令.

稍后,当您使用队列时,您将需要类似的东西(functionQueue.pop())()- 即执行functionQueue.pop,然后执行该调用的返回值以弹出.


Mar*_*iek 6

您还可以使用函数对象的.call()方法.

function doSomething() {
    alert('doSomething');
}

var funcs = new Array();

funcs['doSomething'] = doSomething;

funcs['doSomething'].call();
Run Code Online (Sandbox Code Playgroud)

此外,您还可以将该功能直接添加到队列中:

funcs['somethingElse'] = function() {
    alert('somethingElse');
};

funcs['somethingElse'].call();
Run Code Online (Sandbox Code Playgroud)