【问题标题】:jquery deferred setTimeout loopjquery延迟setTimeout循环
【发布时间】:2012-09-19 14:32:12
【问题描述】:

我有一个函数数组可以使用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};

【问题讨论】:

  • google 'jquery deferred'
  • 我已经这样做了,但找不到适合我的情况。
  • 什么是iidxref?告诉我们那些“funcn”对象
  • 离开 idx。 ref 是对函数的引用。

标签: javascript jquery settimeout jquery-deferred


【解决方案1】:

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

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

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

next();

如果某些功能可以“并行”运行而某些功能相互依赖,事情会变得更加复杂,但您没有提供很多相关信息。

但这也不会有太大的不同。如果您不使用 webworkers,则任何 JavaScript 都会按顺序运行,即使您使用 setTimeout 也是如此。只是执行顺序没有确定。

【讨论】:

  • 是的,我知道,但是我从我的一位客户那里得到了要求,显然是技术人员,他希望像其他语言中的线程一样实现它..
  • 请看我的补充。这并不重要,因为 JavaScript 始终是单线程的。你不能同时运行两个函数(除非你使用 webworkers,这是一个完全不同的故事)。
  • @Felix Kling,如果函数包含 XHttpRequest 或其他浏览器异步调用怎么办?
  • @AresAvatar:那么延迟对象会很有用。但是,OP 没有提到这些功能在做什么。与往常一样:更多信息 -> 更好的答案 ;)
  • @FelixKling 很明显,一个函数可以做任何事情。我需要告诉它吗?
【解决方案2】:

如果我理解您的问题,您放在列表中的每个函数都可以有一个标志,上面写着“等待执行我,直到所有以前的函数都已执行”。因此,您需要做的是向您执行的每个函数添加函数计数和代码以减少计数。像这样的东西,我在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,警报框会立即一个接一个地显示。如果您将其保留为 true,则在 2 秒过去之前,第二个不会显示。

【讨论】:

    猜你喜欢
    • 2016-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-01
    相关资源
    最近更新 更多