我有一个函数可以使用jQuery通过$.each
调用从外部文件加载HTML。
这些ajax调用在$('img').each(function(){
var cotainer_html = $('.cotainer_html').clone();
/* Get Image Content */
$.ajax({
url: '/assets/ajax/get_studio_image.php',
type:'GET',
success:function(data){
cotainer_html.find('.replaceme').replaceWith(data);
}
});
});
循环内运行,我需要在循环继续之前完成这个ajax调用。这是我的代码:
async:false
我知道我可以设置composer update --no-scripts
,但我听说这不是一个好主意。有任何想法吗?
答案 0 :(得分:2)
要实现此目的,您可以将每个请求放入一个数组,并将apply()
该数组放入$.when
。试试这个:
var requests = [];
$('img').each(function(){
var cotainer_html = $('.cotainer_html').clone();
/* Get Image Content */
requests.push($.ajax({
url: '/assets/ajax/get_studio_image.php',
type:'GET',
success:function(data){
cotainer_html.find('.replaceme').replaceWith(data);
}
}));
});
$.when.apply($, requests).done(function() {
console.log('all requests complete');
});
请注意,您要在每个请求中替换相同的内容,因此唯一对UI有影响的是最后一个请求。前面的是多余的。
另请注意, 永远不要使用async: false
。它会锁定浏览器的UI线程,直到请求完成,这使得它看起来已经崩溃到用户。这是一种可怕的做法。使用回调。
OP似乎希望调用以串行方式运行,而不是并行运行
如果是这种情况,您可以使用递归:
function makeRequest($els, index) {
var cotainer_html = $('.cotainer_html').clone();
$.ajax({
url: '/assets/ajax/get_studio_image.php',
type:'GET',
success:function(data){
cotainer_html.find('.replaceme').replaceWith(data);
if ($els.eq(index + 1).length) {
makeRequest($els, ++index);
} else {
console.log('all requests complete');
}
}
});
}
makeRequest($('img'), 0);
答案 1 :(得分:2)
您可以使用伪递归循环:
var imgs = $('img').get();
var done = (function loop() {
var img = imgs.shift();
if (img) {
var cotainer_html = $('.cotainer_html').clone();
/* Get Image Content */
return $.get('/assets/ajax/get_studio_image.php')
.then(function(data) {
cotainer_html.find('.replaceme').replaceWith(data);
}).then(loop);
} else {
return $.Deferred().resolve(); // resolved when the loop terminates
}
})();
这将获取列表中的每个元素,获取所需的图像,然后.then()
重新开始直到没有任何内容。
立即调用函数表达式本身返回Promise
,因此您可以将.then()
调用链接到循环完成后将调用的调用:
done.then(function() {
// continue your execution here
...
});