2011-12-22 32 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