Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/446.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将javascript函数存储在队列中以便最终执行_Javascript_Function_Timeout_Queue - Fatal编程技术网

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

如何将javascript函数存储在队列中以便最终执行,javascript,function,timeout,queue,Javascript,Function,Timeout,Queue,我已经用javascript创建了一个队列类,我想将函数作为数据存储在队列中。这样我就可以建立请求(函数调用)并在需要时响应它们(实际执行函数) 是否有任何方法将函数存储为数据,有点类似于 .setTimeout("doSomething()", 1000); 除非是 functionQueue.enqueue(doSomething()); 它将doSomething()存储为数据,因此当我从队列中检索数据时,将执行该函数 我猜我必须在引号中加上doSomething()->“doSome

我已经用javascript创建了一个队列类,我想将函数作为数据存储在队列中。这样我就可以建立请求(函数调用)并在需要时响应它们(实际执行函数)

是否有任何方法将函数存储为数据,有点类似于

.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
});