2014-03-29 51 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

答案中的代碼已具有此功能。潛在隊列(長度小於批量大小)將僅響應添加另一個項目。但是,已經被服務的隊列將繼續批量服務,直到其長度小於批量。要看到這一點,請按照我上一個註釋(修訂版)中的步驟操作。 –