2017-03-09 102 views
-1

我有一個div的jQuery集合。對於每個div我必須做兩個ajax調用,而第一個調用返回一個由第二個調用使用的id。所有的Ajax調用都需要一些時間(比如說一秒鐘)。定義幾個Ajax調用的順序

如果我做這樣的事情:

$divs.each(function(index, element) { 
    $.get('/some/url').done(function (id) { 
     $.post('/some/other/url?id=' + id).done(function() { 
      $(element).doSomething(); 
     }); 
    }) 
}); 

那麼所有得到通話將首先完成,然後將所有電話。但這並不是錯誤的,我希望儘早執行呼叫,以便儘早向用戶顯示第一個結果。

所以我不想:

get, get, get, get, get, get, get, get, post, post, post, post, post, post, ... 

,而這一點:

get, get, get, get, get, post, get, post, get, post, get, post, get, post, ... 

換句話說,只要對一個div第一次調用完成後,立即開始第二個電話。不要等到所有的第一個電話完成。

我想我必須排隊打電話。我一定要嗎?或者我怎麼能做到這一點?

注意:瀏覽器只能並行執行有限數量的ajax調用。 Firefox中的AFAIK 6默認(Connections per Hostname)。$.get()調用可能很快,但連接限制會導致提取可能需要一些時間。 6個隊列會有幫助嗎?或者我應該爲每個div有一個隊列?

一個額外的任務將是取消整個處理,如果這也是可能的。

更新/解決方案:人們不明白我的問題是什麼。正如一些人現在所建議的,我已經使用了priorityQueue in async庫。有了這個,我可以減少未決連接的數量並控制請求的順序。

+0

如果按照現在的方式進行操作,它確實是最快的。 (除非你能夠將它們全部合併爲一個)。否則,如果延遲了任何獲取請求,用戶將總體上必須等待更長的時間才能完成。 –

+0

@KevinB你是這麼認爲的嗎?我看到整個處理時間不會改變。這只是一種重新排序,因此可以提前顯示一些結果。 – robsch

+0

Gotcha。重新排序會使整體花費更長的時間,但由於前面提出了一些結果,因此會被認爲更快。我建議先取第一個,比如說3,然後取其餘的。 –

回答

0

嗨看看這個方法可以幫助你:

var divs = $("div"); 

recursiveFunction(divs); 

function recursiveFunction(divs){ 
    var element = divs.shift(); 
    $.get('/some/url').done(function (id) { 
    $.post('/some/other/url?id=' + id).done(function() { 
     $(element).doSomething(); 
     if(divs.length > 0){ 
      recursiveFunction(divs); 
     } 
    }); 
    }) 

} 

這樣你可以有GET,POST,GET,POST。

+0

這將創建一個直接的調用序列,對吧?但我想盡可能使用並行執行(Firefox:可能有6個並行調用)。 – robsch

+0

你可以改變它來執行並行執行,你沒看到這個嗎? –

-1

$.get()方法異步返回。

這意味着,你是正確的,所有的$.get()旨意順序執行,同步,他們每個人的然而回調函數(在.done()的內線回調)將被異步調用。

直到回調被調用所需的時間可能會有所不同,而執行$.get()的時間實際上爲0,所以您現在的做法是好的。

0

我認爲你的代碼沒有問題。只是你無法注意到觸發事件。

在過去的異步調用更多的控制,你可以使用https://caolan.github.io/async/docs.html#controlflow

可以說你的每一個AJAX(get和post)調用發生在環路中的每個項目的1秒和處理需要幾毫秒,10毫秒說。因此,對於5個格:

10ms 1st div 
-> get sent 

    20ms 2nd div 
    -> get sent 

    30ms 3rd div 
    -> get sent 

     40ms 4th div 
     -> get sent 

     50ms 5th div 
     -> get sent 

(總共50毫秒)所有的Ajax排隊,但1日的div得到尚在處理,並會在1010ms和後REQ將被髮送

現在,隨着時間的進行後反應,下面會發生

(all get requests sent) 

    1010ms 1st div 
    -> post sent 

     1020ms 2nd div 
     -> post sent 

     1030ms 3rd div 
     -> post sent 

      1040ms 4th div 
      -> post sent 

      1050ms 5th div 
      -> post sent 

所以從上面的順序是

get1, get2, get3, get4, get5, post1, post2, post3, post4, post5 

沒有錯。

+0

沒有錯,但不是最佳。看看這個問題的評論。 – robsch

+0

現在取決於網絡延遲。當網絡響應速度更快時,上述循環會更快。考慮你的請求在20ms內響應,那麼訂單將會與'get1,get2,post1,get3,post2,get4,post3,get5,post4,post5'不同。服務器和相同的應用程序,他們可以在單個AJAX調用中處理。 而我們在談論優化時,爲了初始化UI設置而發送如此多的AJAX請求並不好。 – Pankaj

+0

要優化,您可以一次請求5個ID,然後逐個處理POST請求或同時一次。 – Pankaj

0

你的代碼沒問題。你看到延遲的原因是因爲你所有的get都被扔進了Javascript隊列。有效地執行第一個獲取,然後排隊您的帖子請求,但是,還有其他獲取您的帖子前面已經。

正如其他人指出的那樣,網絡延遲和處理獲取/發佈請求的服務器端時間會加劇此問題。根據用戶體驗來改進延遲問題的唯一真正解決方案是分塊請求。基本上,隊列x獲得請求,比如說4,然後一旦這些請求完成或者使用settimeout並且猜測延遲或者通過事件觸發後續請求,則加載x更多的請求。在我看來,後兩者是不能很好地擴展的黑客。我建議使用第一個選項並下載異步js庫,並使用parallel()方法排隊前四個,並使用可選的回調啓動下一批。沖洗並重復。