2011-12-22 19 views
1

我有一些代碼,看起來像這樣(我在那些不重要的問題的部分):我該如何組jQuery AJAX查詢?

$.ajax({ 
    type: "POST", 
    url: "prepXML.php", 
    data: "method=getartists&user=" + userName + "&amount=" + amount, 
    dataType: "xml", 
    success: function(xml) { 
     $("artist", xml).each(function(){ 
      // calculate and output some stuff and then call getTracks() 
      getTracks(artistName, artistNamePOST, artistPlaycount, divId, artistId); 
     }); 
    } 
}); 

function getTracks(artistName, artistNamePost, artistPlaycount, divId, artistId){ 
    $.ajax({ 
     type: "POST", 
     url: "prepXML.php", 
     data: "method=gettracks&user=" + userName + "&artist=" + artistNamePOST + "&playcount=" + artistPlaycount, 
     dataType: "xml", 
     success: function(xml){ 
      // calculate and output some stuff 
     });      
    } 
}); 

當這個運行時,它調用getTracks()五十次,使相當部分(服務器) CPU在很短的時間內加載完成。我想要做的是將AJAX getTrack()查詢分組,例如每次5個,等到這五個完成後,再調用下一個五個,等待下一個五個完成,然後調用下一個五個等。這樣做的目的是在基本相同的時間減少查詢次數(CPU負載分佈越來越均勻)。

我不確定如何做到這一點,因爲它可以部分擊敗AJAX,但如果可能的話,我仍然希望能夠做到這一點。有人能請我指出正確的方向嗎?謝謝。

爲了更好地理解我需要的和應用程序的功能,下面是鏈接到app。它可以試用任何lastfm尼克(如果你沒有一個,你可以使用我的 - 「pootzko」)。我希望我可以把鏈接放在帖子中(?),如果沒有,請隨時刪除它..

+2

你爲什麼不只是隨着自己的音樂數據時,你做的返回軌道的數組'方法= getartist'那麼你只需要做的(每個藝術家)一所服務器調用。也許有一種叫做'getartistwithtracks'的方法 – musefan 2011-12-22 10:39:10

+1

@musefan - 這與lastfm api一起工作,其中getartists首先查詢lastfm並獲得最高級聆聽arist的列表,之後它必須對lastfm進行新的單獨查詢以獲取關於每個這些藝術家。 – pootzko 2011-12-22 10:50:33

+0

看看這個:[一堆ajax調用](http://stackoverflow.com/questions/42425885/trying-to-make-2-ajax-calls-via-jquery-and-then-prepending-the-data -taken-from/42426722#42426722) – 2017-02-23 21:57:43

回答

1

我只考慮檢索用戶點擊過的藝術家的曲目信息。或者可能通過單個請求檢索數據全部(或許在檢索後通過setTimeout()分批處理它)。

可是事情大致如下的線路可能工作在同一時間只做了五項要求:

$.ajax({ 
    type: "POST", 
    url: "prepXML.php", 
    data: "method=getartists&user=" + userName + "&amount=" + amount, 
    dataType: "xml", 
    success: function(xml) { 
     var artists = $("artist", xml), 
      i = 0, 
      c = 0; 

     function getTracksComplete() { 
     if (--c === 0) 
      nextBatch(); 
     } 

     function nextBatch() { 
     for(; c < 5 && i < artists.length; i++, c++) { 
      // artists[i] is the current artist record  
      // calculate and output some stuff and then call getTracks() 
      getTracks(artistName, artistNamePOST, artistPlaycount, divId, artistId, 
         getTracksComplete); 
     } 
     } 

     // Optional - if you need to calculate statistics on all the artists 
     // then do that here before starting the batches of getTracks calls 
     artists.each(function() { /* do something */ }); 

     // Kick of the first batch of 5 
     nextBatch(); 
    } 
}); 

function getTracks(artistName, artistNamePost, artistPlaycount, divId, artistId, 
        callback){ 
    $.ajax({ 
     type: "POST", 
     url: "prepXML.php", 
     data: "method=gettracks&user=" + userName + "&artist=" + artistNamePOST + "&playcount=" + artistPlaycount, 
     dataType: "xml", 
     success: function(xml){ 
      // calculate and output some stuff 
     }, 
     complete : function() { 
      if (callback) callback(); 
     });      
    } 
}); 

以上只是我的頭頂部(所以我沒有時間來建立它可以縮放或繪製它),但是我們的想法是,不是一次使用.each()來循環所有藝術家,而是緩存jQuery對象並一次完成一些操作。調用函數nextBatch()(它對成功處理程序是本地的,因此可以訪問局部變量)將運行一個循環,該循環僅調用getTracks() 5次,但是從上次停止的位置開始處理。同時getTracks()已稍微更新以接受回調函數,因此當 ajax調用完成時(並且注意我們在完成而不是成功時執行此操作以防出錯),它可以讓主進程知道它已完成。在回調中,我們會跟蹤已完成的數量以及他們何時再次致電nextBatch()

+0

complete + callback很好,謝謝! – pootzko 2011-12-22 13:52:55

0

很難清楚地理解你的應用邏輯,但我認爲更好的方法應該是收集之前所有需要發送的數據(JSON對象中的50個條目),然後僅調用一次getTracks函數,僅傳遞一個JSON對象。

1

要麼包含從getartists返回的數據中的所有曲目信息,要麼只有在有人想要查看特定藝術家的曲目時才調用getTracks

例如

顯示所有藝術家,並有一個「查看曲目」選項。只有一次點擊,你才能獲得曲目。

對我來說這是最好的選擇,因爲如果你爲所有的藝術家加載所有的曲目,那麼有很多數據可能並不需要。沒有人會想要瀏覽所有的藝術家和所有的藝術家的軌道(除非特別想要)。

+0

事情是,實際上所有的數據都用來計算一些統計數據。 – pootzko 2011-12-22 11:16:51

+0

如果它只是用來計算統計數據,然後顯示統計數據,那麼最好只在'getartists'中完成這一切,然後返回統計數據? – 2011-12-22 11:19:14

+0

然後會發生的事情是,應用程序「掛起」30-40秒,直到它被全部計算出來,所以我會說普通的ajax比這個更好。如果可能,我只是想「改善」。我在原始帖子中添加了一個應用程序鏈接,以便更好地瞭解它的功能,如果這有幫助的話。 – pootzko 2011-12-22 11:26:52

1

我的解決辦法是將處理所有的藝術家數據到陣列,然後開始執行在5批次.ajax()請求當這些5級的請求完成後,執行下一批次等

HERE是一個工作示範。

// just success changed 
$.ajax({ 
    type: "POST", 
    url: "prepXML.php", 
    data: "method=getartists&user=" + userName + "&amount=" + amount, 
    dataType: "xml", 
    success: function(xml) { 
    var data = []; 
    // prepare the data 
    $("artist", xml).each(function(){ 
     data.push({ name: artistName /** rest of data */ }); 
    }); 
    // start processing the data 
    processData(data, 0); 
    } 
}); 

// process the data by sending requests starting from index 
function process(data, index) { 
    var xhrs = []; 
    for (var i = index; i < index + 5 && i < data.length; i++) { 
    (function(data) { 
     xhrs.push($.ajax({ 
     type: "POST", 
     url: "prepXML.php", 
     data: "method=gettracks&user=" + data.name /** rest of the data */ 
     dataType: "xml", 
     success: function(xml) { 
      // calculate and output some stuff 
     } 
     })); 
    })(data[i]); 
    } 

    // when current xhrs are finished, start next batch 
    $.when.apply(this, xhrs).then(function() { 
    index += 5; 
    if (index < data.length) { 
     process(data, index); 
    } 
    }); 
} 
+0

+ +1爲工作解決方案/想法。我選擇了@nnnnnn的解決方案,因爲對我來說,它更容易理解和實施。感謝你的努力。 :) – pootzko 2011-12-22 13:55:04