【问题标题】:JavaScript Function QueueJavaScript 函数队列
【发布时间】:2011-06-24 13:53:47
【问题描述】:

我有很多需要连续运行的功能,但不是在另一个完成之前。我需要的是一种方法,让这些函数仅在前一个函数成功完成后才运行。有什么想法吗?

Function1();
Function2();
Function3();
Function4();
Function5();

【问题讨论】:

  • 您的代码应该可以正常工作...(如果“成功完成”是指函数返回)
  • 你的函数中有异步的东西吗?如果没有,我看不出有问题。
  • 我的大部分函数都包含 AJAX 调用。每一个都取决于上一次调用的成功。
  • 你可以考虑使用deferring calls(从 jQuery 1.5 开始)。他们可能有一种方法可以编写绑定到成功/失败事件的插件,因此它可以直接放入 jQuery 的环境中。
  • 对 jQuery 延迟的好评论。我以前在 Twisted 中使用过它们,但不知道它们在新的 jQuery 中。

标签: javascript jquery javascript-events


【解决方案1】:

你可以这样使用:

var FunctionQueue = (function(){
    var queue = [];
    var add = function(fnc){
        queue.push(fnc);
    };
    var goNext = function(){
        var fnc = queue.shift();
        fnc();
    };
    return {
        add:add,
        goNext:goNext
    };
}());

并像这样使用它:

var fnc1 = function(){
    window.setTimeout(function(){
        alert("1 done");
        FunctionQueue.goNext();
    }, 1000);
};

var fnc2 = function(){
    window.setTimeout(function(){
        alert("2 done");
        FunctionQueue.goNext();
    }, 5000);
};

var fnc3 = function(){
    window.setTimeout(function(){
        alert("3 done");
        FunctionQueue.goNext();
    }, 2000);
};

FunctionQueue.add(fnc1);
FunctionQueue.add(fnc2);
FunctionQueue.add(fnc3);
FunctionQueue.goNext();

几年后编辑: 人们解决此问题的另一种方法是传入一个next 函数,您可以调用该函数来继续该链。像这样:

var Queue = function(arr){
    var index = 0;
    var next = function(){
        if (index >= arr.length) {return;}
        arr[index++](next);
    };
    return next;
};

var fn1 = function(next){
    console.log("I am FN1");
    next();
};

var fn2 = function(next){
    console.log("I am FN2");
    setTimeout(next,1000);
};

var fn3 = function(next){
    console.log("I am FN3");
    setTimeout(next,3000);
};

var fn4 = function(next){
    console.log("I am FN4");
    setTimeout(next,1000);
};

Queue([fn1, fn2, fn3, fn4])();

【讨论】:

    【解决方案2】:

    你可以创建一个队列函数:

    function Queue(arr) {
        var i = 0;
        this.callNext = function() { 
            typeof arr[i] == 'function' && arr[i++]();
        };
    }
    

    如果这些是你的功能......

    function f1() {
        alert(1);   
    }
    
    function f2() {
        alert(2);   
    }
    
    function f3() {
        alert(3);   
    }
    

    ...您只需在新的 Queue 实例中传递它们(它们的引用):

    var queue = new Queue([f1, f2, f3]);
    

    然后你执行callNext()依次调用函数:

    queue.callNext();
    queue.callNext();
    queue.callNext();
    

    现场演示: http://jsfiddle.net/CEdPS/3/

    【讨论】:

      【解决方案3】:

      你为什么不完全按照你展示的那样做,把它们列在一个覆盖函数中?

      function do_1_to_5() {
          Function1(); 
          Function2(); 
          Function3(); 
          Function4(); 
          Function5();
      }
      

      如果您的函数包含 AJAX 调用,那么您需要在处理 AJAX 调用的回调函数的末尾连接它们。

      【讨论】:

      • 这正是我所做的,将下一个函数放在 jquery 的 $.ajax 调用的成功回调中。我只是认为可能有更好的解决方案。
      【解决方案4】:

      为了确保它们连续运行,您可以从每个返回一个值,并在后续一个中使用该返回值...

      function do_1_to_5() {
      
          r1 = Function1(); 
          r2 = Function2(r1); 
          r3 = Function3(r2); 
          r4 = Function4(r3); 
          r5 = Function5(r4);
      
      }
      

      【讨论】:

        【解决方案5】:

        您不需要所有这些机器,只需将您的函数放在一个数组中即可。然后你可以循环它们。

        var runThese = [
            Function1,
            Function2, 
            Function3,
            Function4,
            Function5
        ];
        

        JavaScript 是单线程的,因此您可以保证一个在下一个开始之前完成。

        for (var i = 0; i < runThese.length; i++) {
            runThese[i]();
        }
        

        或者由于您的函数具有确定性名称,您可以完全避免使用数组:

        for (var i = 1; i <= 5; i++) {
            window["Function" + String(i)]();
        }
        

        【讨论】:

        • 没有看到每个函数需要等待前一个函数异步的注释。所以这毕竟不是你需要的。在不了解函数内容的情况下无法真正正确回答问题。
        【解决方案6】:

        查看 async.js - 它提供了一种链接函数的机制,以便它们异步执行或一个接一个地执行,并以一种极好的方式从所有执行的函数中捕获结果和/或错误。

        https://github.com/caolan/async

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-01-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-10-16
          • 1970-01-01
          • 1970-01-01
          • 2018-07-10
          相关资源
          最近更新 更多