2014-03-29 48 views
2

我正在实现各种信息的队列系统。当它达到一定数量时,我发送一个ajax请求....用户输入数据,当它达到某一点时我发送它。但是,用户仍然可以输入数据。我不想失去那..因此,我想我可以使用$.Deferred/promise,而将数据存储到某个点..发射ajax,并且只允许一个新的请求,当以前的延期成功...另外,如果输入的数据然后增加到我必须再次发送它的时候,我就可以了。延迟和ajax和排队功能

我很难把我的大脑围绕如何实现的方法进行包装。

===>捕获数据

=======> 'n' 个数据量被输入

=============>此举数据放入“准备好”的桶中。 (任意的,让用户输入10个输入字段,并存储到一个数组中,当数组达到10时,发送它)。

=============>火阿贾克斯与10个项目

在此期间,用户仍然可以输入数据。我想确保我仍然捕获它,并保持queing,并在10发送。

我在考虑排队系统与延期。不知道我是否过度思考这一点。

+0

您的方法似乎很好......您的问题是什么? – Hamish

+0

我不完全熟悉Deferred的足够执行他们没有仔细思考。我正在寻找一种方法来实现上述目标。如果我只是编写了它,那么确实很快就完成了 - 但我认为我会因延迟带来的一些权力而失去作用。但是,我再一次对他们不熟悉 - 一直在阅读它们。很难把握。 – user1492442

回答

3

由于$.ajax()返回的jqXHR对象是可以使用的Promise。

var data = { 
    // captured data goes here 
}; 

function sendData(val){ 
    // jqXHR object (which contains a promise) 
    return $.ajax('/foo/', { 
     data: { value: val }, 
     dataType: 'json', 
     success: function(resp){ 
      // do whatever needed 
     } 
    }); 
} 

function when(){ 
    $.when(sendData(data)).done(function (resp) { 
     when(); 
    }); 
} 

when(); // use this within the if switch 

DEMO

+0

谢谢!仍然等待更好的代表,所以我可以upvote等..那些帮助。谢谢一堆! – user1492442

+0

@ user1492442我已更正错误,并添加了演示链接。很高兴这有助于帮助 –

+0

code-jaff - 你将如何实现Roamer下面做的事情,因为你有一个批处理大小。 – user1492442

2

假设您的队列是数组dataQueue,那么你可以做这样的事情:

var dataQueue = [];//sacrificial queue of items to be sent in batches via AJAX request 
var batchSize = 10; 
var requesting = false;//flag used to suppress further requests while a request is still being serviced 

//addToQueue: a function called whenever an item is to be added to he queue. 
function addToQueue(item) { 
    dataQueue.push(item); 
    send();//(conditional on queue length and no request currently being serviced) 
} 

function send() { 
    if(dataQueue.length >= batchSize && !requesting) {//is the queue long enough for a batch to be sent, and is no ajax request being serviced 
     $.ajax({ 
      url: '/path/to/server/side/script', 
      data: JSON.stringify(dataQueue.splice(0, batchSize)),//.splice removes items from the queue (fifo) 
      ... //further ajax options 
     }).done(handleResponse).fail(handleFailure).always(resetSend); 
     requesting = true; 
    } 
} 

function handleResponse(data, textStatus, jqXHR) { 
    //handle the server's response data here 
} 
function handleFailure(jqXHR, textStatus, errorThrown) { 
    //handle failure here 
} 
function resetSend() { 
    requesting = false;//Lower the flag, to allow another batch to go whenever the queue is long enough. 
    send();//Call send again here in case the queue is already long enough for another batch. 
} 

DEMO

注:

  • 没有特别的理由从send中返回jqXHR(或其他任何东西),但是如果您的应用程序会受益,则一定要这样做。
  • resetSend不需要被称为.always处理程序。从.done处理程序(而不是.error处理程序)调用将具有“死于故障”的效果。
  • 为了减少您的命名空间(全局或其他)成员的数量,你可以选择封装在一个构造器函数或单命名空间格局,这两者都是很琐碎的整个事情。
  • 封装在构造函数中,可以让你有两个或多个具有所需行为的队列,每个队列都有自己的设置。
  • 该演示有一些额外的代码行,以使该过程可观察。
  • 在演示中,您可以将批处理大小设置为15,add-add-add使队列长度达到12,然后将批处理大小减小到5并添加另一个项目。您应该看到两个连续的请求,以及队列中的3个剩余项目。
+0

我有一个问题 - 可以说在先前的send()完成之前,que已经达到10的极限(批量)。然后它将不会再次启动,直到另一个项目移动到que,然后再重新初始化它。对?这就是为什么我在考虑推迟排队,以便每当它结束时,如果先前的调用比填充其批量大小的时间更长,则“下一个排队”排队会被触发并且不会被排除。 – user1492442

+0

答案中的代码已具有此功能。潜在队列(长度小于批量大小)将仅响应添加另一个项目。但是,已经被服务的队列将继续批量服务,直到其长度小于批量。要看到这一点,请按照我上一个注释(修订版)中的步骤操作。 –