Javascript 在';每个';功能

Javascript 在';每个';功能,javascript,jquery,ajax,wordpress,Javascript,Jquery,Ajax,Wordpress,本主题将在其他几个问题中讨论,但我在将建议的方法应用到本用例中时遇到了一些困难。我有一个复选框列表,用户可以在其中选择n个子网站发布他们的文章。因为这个列表可能会增加到100+,所以我需要一种有效的方法来对每个列表执行昂贵的任务。如果需要一段时间也没关系,只要我能提供视觉反馈,所以我计划对每个复选框项应用“进行中”样式作为其工作方式,然后在成功发布后移动到列表中的下一项。另请注意:我在WordPresswp\u ajax\ucode>hook中工作,但是PHP方面工作得很好,这主要集中在JS解决

本主题将在其他几个问题中讨论,但我在将建议的方法应用到本用例中时遇到了一些困难。我有一个复选框列表,用户可以在其中选择n个子网站发布他们的文章。因为这个列表可能会增加到100+,所以我需要一种有效的方法来对每个列表执行昂贵的任务。如果需要一段时间也没关系,只要我能提供视觉反馈,所以我计划对每个复选框项应用“进行中”样式作为其工作方式,然后在成功发布后移动到列表中的下一项。另请注意:我在WordPress
wp\u ajax\ucode>hook中工作,但是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: {

        }
    });
}

实际上,执行同步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请求。如果可以,请尝试将它们组合起来,这样会更好更快。

如果不能将整个块传递给服务器进行批量处理,可以使用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}
    });
}

我没有这方面的测试环境,因此您可能需要根据您的用例对其进行调整。

您不应该使用调用AJAX函数的循环,而是将数组(或对象)作为AJAX参数发送,并让服务器端代码执行循环。