在每个'内创建ajax请求循环。功能

时间:2014-11-17 13:59:41

标签: javascript jquery ajax wordpress

本主题还包含其他几个问题,但我在将这些建议的方法应用于此用例时遇到了一些困难。我有一个复选框列表,用户可以选择 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: {

        }
    });
}

2 个答案:

答案 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}
    });
}

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