Rya*_*ney 5 ajax jquery asynchronous jquery-callback
这可能是我对AJAX如何运行的误解,但我有一种情况,即在GET请求实际完成之前$.get调用callback(.always()).至少,这就是它的样子.
代码
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' );
Run Code Online (Sandbox Code Playgroud)
代码的作用
本质上,代码执行此操作:循环浏览视频嵌入代码列表.对于循环的每次迭代for,获取有关每个视频的详细信息并将这些细节推送到多维数组中.完成获取所有视频后,请调用.always()回调,该回调会将视频分类为按字母顺序排列的播放列表并附加到该页面.
问题
该.always()回调有时所有的影片已被取出之前被调用.播放列表中有9个视频,但有时在回拨被触发之前只返回6或7个视频,这意味着我的播放列表有点短.我已通过alert()键数和使用控制台对此进行了测试.我所看到的是6-7的视频会返回,然后在alert()回调火灾,那么剩下的视频被返回.
我的问题:
为什么会这样?我认为在AJAX请求完成后.always()触发了回调.这是不是意味着在回调被触发之前应该返回所有视频?我怀疑它与AJAX中的"A"有关,但我认为回调的目的是解释这一点.非常感谢任何帮助我理解的东西.谢谢!always()
你设置它的方式.always,一旦循环中的最后一个 ajax请求完成,回调就会触发.这可能与其他人无关.当循环中的所有请求都已完成或外部请求已完成时,我无法判断是否要触发它.
对于外部请求,这很容易.只是打电话给.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 */
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用.pipe:
//Create initial deferred object
var jqxhr = $.Deferred();
...for loop...
jqxhr = jqxhr.pipe($.get(...
jqxhr.always(function () { /* callback */
Run Code Online (Sandbox Code Playgroud)