本主题还包含其他几个问题,但我在将这些建议的方法应用于此用例时遇到了一些困难。我有一个复选框列表,用户可以选择 n 子站点发布他们的帖子。由于这个列表可能会增长到100+,我需要一种有效的方法来执行每个列表上的昂贵任务。如果需要一段时间,只要我提供视觉反馈,这是可以的,所以我计划在每个复选框项目中使用“进行中”样式作为其工作,然后在成功发布后移动到列表中的下一个项目。另请注意:我正在使用WordPress wp_ajax_
钩子,但PHP方面的工作正常,这主要集中在JS解决方案上。
此代码现在正在运行(console.logs留下来进行调试),但我看到多次警告反对使用async: true
。如何以更有效的方式实现瀑布AJAX循环?
//Starts when user clicks a button
$("a#as_network_syndicate").click( function(e) {
e.preventDefault(); //stop the button from loading the page
//Get the checklist values that are checked (option value = site_id)
$('.as-network-list').first().find('input[type="checkbox"]').each(function(){
if($(this).is(':checked')){
blog_id = $(this).val();
console.log(blog_id+' started');
$(this).parent().addClass('synd-in-progress'); //add visual feedback of 'in-progress'
var process = as_process_syndication_to_blog(blog_id);
console.log('finished'+blog_id);
$(this).parent().removeClass('synd-in-progress');
}
});
});
function as_process_syndication_to_blog(blog_id){
var data = {
"post_id": $('#as-syndicate_data-attr').attr("data-post_id"), //these values are stored in hidden html elements
"nonce": $('#as-syndicate_data-attr').attr("data-nonce"),
"blog_id": blog_id
};
var result = as_syndicate_to_blog(data);
console.log('end 2nd func');
return true;
}
function as_syndicate_to_blog(data){
$.ajax({
type : "post",
dataType : "json",
async: false,
url : ASpub.ajaxurl, //reference localized script to trigger wp_ajax PHP function
data : {action: "as_syndicate_post", post_id : data.post_id, nonce: data.nonce, blog_id: data.blog_id},
success: function(response) {
if(response.type == "success") {
console.log(response);
return response;
} else {
}
},
error: {
}
});
}
答案 0 :(得分:2)
确实,执行同步AJAX请求很糟糕,因为它会在整个AJAX调用期间阻塞浏览器。这意味着用户在此期间无法与您的网页进行互动。在你的情况下,如果你做了30次AJAX调用,比如0.5秒,浏览器将在15秒内被阻止,这很多。
无论如何,你可以按照这种模式做点什么:
// some huge list
var allOptions = [];
function doIntensiveWork (option, callback) {
// do what ever you want
// then call 'callback' when work is done
callback();
}
function processNextOption () {
if (allOptions.length === 0)
{
// list is empty, so you're done
return;
}
// get the next item
var option = allOptions.shift();
// process this item, and call "processNextOption" when done
doIntensiveWork(option, processNextOption);
// if "doIntensiveWork" is asynchronous (using AJAX for example)
// the code above might be OK.
// but if "doIntensiveWork" is synchronous,
// you should let the browser breath a bit, like this:
doIntensiveWork(option, function () {
setTimeout(processNextOption, 0);
});
}
processNextOption();
注意:正如Karl-AndréGagnon所说,你应该避免使用这种技术做很多AJAX请求。如果可以的话,尝试将它们组合起来,它会更好更快。
答案 1 :(得分:0)
如果无法将整个块传递给要批量处理的服务器,则可以使用jQuery队列。这是使用您的示例代码作为基础:
var $container = $('.as-network-list').first();
$container.find('input[type="checkbox"]:checked').each(function(){
var $input = $(this);
$container.queue('publish', function(next) {
var blog_id = $input.val(),
$parent = $input.parent();
console.log(blog_id+' started');
$parent.addClass('synd-in-progress'); //add visual feedback of 'in-progress'
as_process_syndication_to_blog(blog_id).done(function(response) {
console.log(response);
console.log('finished'+blog_id);
$parent.removeClass('synd-in-progress');
next();
});
});
});
$container.dequeue('publish');
function as_process_syndication_to_blog(blog_id){
var data = {
"post_id": $('#as-syndicate_data-attr').attr("data-post_id"), //these values are stored in hidden html elements
"nonce": $('#as-syndicate_data-attr').attr("data-nonce"),
"blog_id": blog_id
};
return as_syndicate_to_blog(data).done(function(){ console.log('end 2nd func'); });
}
function as_syndicate_to_blog(data){
return $.ajax({
type : "post",
dataType : "json",
url : ASpub.ajaxurl, //reference localized script to trigger wp_ajax PHP function
data : {action: "as_syndicate_post", post_id : data.post_id, nonce: data.nonce, blog_id: data.blog_id}
});
}
我没有这方面的测试环境,因此您可能需要针对您的用例进行调整。