2013-01-06 50 views
5

这可能是我对AJAX函数的误解,但我有一种情况,在此之前调用$.get回调函数(.always()) GET请求实际上完成。至少,这就是它的样子。

守则

var apiRequest = 'some/url/'; 

// fetch list of video embed codes 
$.get(apiRequest, function(embed_codes) { 

    // added this per Explosion Pills' answer 
    var jqxhrs = []; 

    // for each embed code, get video details (name, duration, etc.) 
    for (var i = 0; i < embed_codes.length; i++) { 
     var videoDetailsRequest = '/v2/assets/' + embed_codes[i]; 
     //..declare vars.. 

     // fetch video details 
     var jqxhr = $.get(videoDetailsRequest, function(video) { 
      // build playlist entry for each video 
      playlistItem = '<li><h3>' + video.name + '</h3><p>' + video.description + '</p></li>'; 

      // create object of video HTML, with key = "video name" for sorting later 
      videoArray[video.name] = playlistItem; 
     }, 'jsonp') 

     // added this per Explosion Pills' answer 
     jqxhrs.push(jqxhr); 
    } 

    // updated from jqxhr.always(function() { 
    $.when(jqxhrs).always(function() { 
     // create array of keys 
     for (k in videoArray) { 
      if (videoArray.hasOwnProperty(k)) { keys.push(k); } 
     } 

     // append alphabetized list of videos to the page... 
    }); 
}, 'jsonp'); 

什么代码没有

从本质上讲,该代码执行此操作:遍历的视频嵌入代码的列表。对于for循环的每次迭代,获取有关每个视频的详细信息并将这些详细信息推送到多维数组中。完成提取所有视频后,请拨打.always()回拨,将视频按照字母顺序排列,然后附加到页面。

的问题

.always()回调有时之前调用所有的视频都被取出。播放列表中有9个视频,但在回调被触发前有时候只有6或7个视频会被返回,这意味着我的播放列表有点短。我已通过alert()键和使用控制台测试了这一点。我所看到的是,6-7个视频将返回,然后alert()在回调火灾,然后剩余的视频被返回。

我的问题:

这究竟是为什么?我认为在 AJAX请求完成后.always()回调触发。这是不是意味着所有的视频都应该在之前返回回调被解雇?我怀疑它与AJAX中的“A”有关,但我认为always()回调的目的是为了解决这个问题。任何帮助我理解的东西都非常感谢。谢谢!

回答

5

您设置的方式,只要循环中的上一个 ajax请求完成,.always回调就会触发。相对于其他人而言,这可能发生错误。当循环中的所有请求都完成或外部请求完成时,我无法确定是否希望它触发。

对于外部请求,这很容易。只需连线.always(或.done,我相信它们是相同的,后者是首选)。

如果你想让它完成时,所有其他的Ajax请求完成后,您可以使用$.when,当所有递延对象是完整的,其检查:

var jqxhrs = []; 
    ...for loop... 
    var jqxhr = $.get(videoDetailsRequest 
    ... 
    }, 'jsonp'); 
    jqxhrs.push(jqxhr); 
... 
$.when.apply(undefined, jqxhrs).always(function() { /* your intended callback */ 

或者,你可以使用.pipe

//Create initial deferred object 
var jqxhr = $.Deferred(); 
    ...for loop... 
    jqxhr = jqxhr.pipe($.get(... 
jqxhr.always(function() { /* callback */ 
+0

感谢您的回答!我没有运气与.pipe(),但'$。当()'在_almost_那里。当我查看控制台日志时,回调中的'videoArray'首先出现,已经排序,然后_ console_控制台在'for'循环中记录每个单独的视频。 Whaaat?无论出于何种原因,通过此路线可以防止回调中的for循环执行,所以我永远不会得到'keys'数组,这意味着我无法构建我的播放列表。任何想法,为什么?我更新了我的答案,以包含构建播放列表的代码。 –

+1

@Ryan可能'$ .when'不喜欢数组作为参数,所以试试'$ .when.apply(undefined,jqxhrs)'(这会调用'$ .when'方法,但不是传递一个数组就可以工作,就好像它调用'$ .when(jqxhrs [0],jqxhrs [1] ...)'。 –

+0

工作得很好!谢谢!我明白了,我必须做所有这些额外的工作因为我在'for'循环内进行AJAX调用(它本身在另一个'.get()'请求中)?在正常情况下,应该在AJAX请求完成后触发'.always()'回调,对吗? –

相关问题