jquery延迟setTimeout循环

时间:2012-09-27 18:10:24

标签: javascript jquery settimeout jquery-deferred

我有一个函数数组来迭代setTimeout函数以提供非阻塞效果,但是任何或所有函数都可以有顺序标志,这意味着只有在执行了之前的函数后才能执行。有人建议我使用jquery.deferred。我从来没有使用过jquery延迟。

while(that.funcns.length>0){
  fn=that.funcns.splice(0,1)[0];
  fn.idx=i;
  window.setTimeout(function(){
    fn.ref(); //call function reference     
  },(idx==0)?idx:1000);
}
//fn - {ref:functionReference,order:true/false};

2 个答案:

答案 0 :(得分:0)

您可以使用延迟对象,但为什么不只使用一个计时器并逐个调用这些函数?

var funcs = [/* array of functions */];

function next() {
    var func = funcs.shift();
    if(func) {
        func();
        setTimeout(next, 100);
    }
}

next();

如果某些功能可以“并行”运行并且某些功能依赖,则事情会变得更复杂,但是您没有提供大量有关此功能的信息。

但它也没有太大的区别。如果您不使用Webworkers,即使您使用setTimeout,也会按顺序运行任何JavaScript。只是执行的顺序没有确定。

答案 1 :(得分:0)

如果我理解你的问题,你在列表中放入的每个函数都可以有一个标记,上面写着“等待执行我,直到所有先前的函数都被执行”。因此,您需要做的是为您执行的每个函数添加函数计数和代码以减少计数。像这样的东西,我把副本放在jsFiddle here中:

var funcCount = 0, funcList = [];

function executeFunctions() {
    var nextFunc;

    while (funcList.length > 0) {
        // Check next in list, if we need to wait, make sure we wait
        nextFunc = funcList[0];
        if (nextFunc.needToWait) {
            if (funcCount > 0) {
                // Try again later
                setTimeout(executeFunctions, 100);
                return;
            }
        }

        // Since we are now going to execute, remove from list and execute
        funcList.splice(0, 1);
        funcCount += 1;    // nextFunc will subtract 1 on completion
        setTimeout(nextFunc, 100);
    }
}

// For async functions to call back to completion
function completionCallback() {
    funcCount -= 1;
}

为了测试它我已经定义了两个函数。第一个使用长超时模拟异步。第二个设置了等待标志,因此需要等待第一个。然后我将它们都添加到列表中并测试它:

// Example function 1 is simulated async
function example1() {
    alert("Example1");

    // Simulate async call with completion callback function, e.g. XHttpRequest
    setTimeout(completionCallback, 2000);
}    
example1.needToWait = false;     // Not flagged

// Example function is flagged as need others to complete first
function example2() {
    alert("Example2");

    funcCount -= 1;        
}
example2.needToWait = true;

// Setup function list to execute example1 then example2
funcList.push(example1);
funcList.push(example2);

// OK, test it
executeFunctions();

如果将function2标志更改为false,则会立即显示一个接一个的警告框。如果你把它保留为真,那么第二个就会在2秒过后才显示出来。