繁体   English   中英

队列函数调用

[英]Queue function calls

在我的小提琴中,我有以下称为trice的函数(模拟用户快速连续启动三次)

https://jsfiddle.net/tvs1zdw9/1/

function test(){
  var r = $.Deferred();

  //simulate ajax call that loads data and takes 2 seconds
  setTimeout(function(){
    r.resolve();
    count++;
    $('#here>i').html(count);
  },2000);

  return r;
}

目标:不管用户持续按下按钮有多快,我总是要等到功能完成后才能再次运行。

我已经添加了一个deferrer(r)来指示何时使用以下代码完成该功能:

test().done(function(){
    console.log('done running function');
});

例:

  • 用户快速连续单击按钮3次
  • 函数被调用了三遍(快于它可以完成的次数)
  • 有一个“队列”被创建
  • 每当函数完成而不是之前,“队列”中的下一个项目就会开始

我发现了jQuery队列功能,但似乎仅适用于链接到DOM中项目的功能……也许我不太了解。 此处: https//api.jquery.com/queue/

谁能帮助我建立一个队列,然后在每个功能完成后进行处理?

如果实现,代码可以非常简单,甚至优雅:

  • 队列作为承诺链
  • 要排队的东西作为功能。

首先,可重用函数形成专用队列并返回一个函数,通过该函数可以将项目添加到队列中。

function AsyncQueue(stopOnError) {
    var p = $.when(); // a resolved promise, which acts as the seed of a .then() chain (ie a "queue").
    return function(fn) {
        p = p
          .then(null, function() { if(!stopOnError) return $.when(); }) // prevent propagation of a previous error down the chain.
          .then(fn);
        return p;
    }
}

这样,队列(promise链)将“自我管理”,因此不再需要runningrunQueue()

现在您可以写:

function goodDelay() { // simulate a successful request
    return $.Deferred(function(dfrd){ setTimeout(dfrd.resolve, 1000); });
}
function badDelay() { // simulate a failed request
    return $.Deferred(function(dfrd){ setTimeout(dfrd.reject, 1000); });
}

var queue = AsyncQueue(false); // `queue` is a function with its own private .then chain.
queue(goodDelay).then(successHandler, errorHandler);
queue(badDelay).then(successHandler, errorHandler);
queue(goodDelay).then(successHandler, errorHandler);

function successHandler() {
    console.log('success:');
}
function errorHandler() {
    console.log('error:');
}

stopOnError工作方式如下:

  • false :内部错误处理程序可确保队列始终沿成功路径前进,而不管先前的结果如何。
  • true :内部错误处理程序无效,并且队列采用其自然的(jQuery)行为将错误传播到链下。 发生错误后,将不再触发其他排队的函数,尽管它们的外部errorHandlers(如果存在)将被触发,并且将被告知所有相同的失败原因。

带有stopOnError DEMO为false
带有stopOnError 演示

解决方案: https : //jsfiddle.net/jqqmrv4L/1/

我创建了一个可变队列

var queue = [];

当函数在完成之前被调用时,我将进入队列。

  var count = 0;
  var running = false;
  var queue = [];
    var test = function(){
    var r = $.Deferred();

    if(!running){
      running = true;

      //simulate ajax call that loads data and takes 2 seconds
      setTimeout(function(){
        r.resolve();
        count++;
        $('#here>i').html(count);
        running = false;
      },2000);
    } else {
        console.log('called whilst running');
      queue.push('234');
    }

    return r;
    }

然后,我还有另一个函数来处理队列,该队列在初始函数完成后被调用,如下所示:

test().done(function(){
        console.log('done running function, checking queue');
      runqueue();
    });

这里是处理队列的最后一个“运行队列”函数:

function runqueue(){
         if(queue.length){
            console.log('queue has!', queue.length);
        //runqueue();
        test().done(function(){
            console.log('queue item completed');
          queue.splice(0,1); //delete this because it has ran
          //runqueue();
        });
      } else {
        console.log('queue done');
      }
  }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM