javascript中的非阻止代码问题

时间:2014-03-06 18:18:55

标签: javascript jquery ajax blocking

我试图制作一个暴力投票投票脚本。

$('#vote').click(function(e) {                                      
    var noOfvotes = 0;
    var noOfattempt =0;
    var noOffail =0;

    for(var i =0 ; i<500;i++){
        $.ajax({
            url: 'http://www.example.com/survey/',
            type: 'POST',                   
            data: {poll: '123',
                   vote:"option3"                             
                  },
        })
            .done(function() {
                noOfvotes++;
            })
            .fail(function() {
                noOffail++;
            })
            .always(function() {
                noOfattempt++;
            });
    }
    //Result printing
    console.log('No of attempt :' + noOfattempt);       
    console.log('No of done :' + noOfvotes);
    console.log('No of fail :' + noOffail); 
});

我遇到的问题是结果打印是在这些ajax请求完成之前执行的。所以在控制台上输出是这样的

No of attempt :0   
No of done :0
No of fail :0

但是我需要在所有Ajax请求完成后执行这些行。如何为这种情况制作阻止代码。

3 个答案:

答案 0 :(得分:4)

将请求堆叠在一个数组中,并使用$.when确定它们何时完成

$('#vote').click(function (e) {
    var XHR         = [],
        noOfvotes   = 0,
        noOfattempt = 0,
        noOffail    = 0;

    for (var i = 0; i < 500; i++) {
        XHR.push(
            $.ajax({
                url: 'http://www.example.com/polling/',
                type: 'POST',
                data: {
                    poll: '123',
                    vote: "option3"
                },
            }).done(function () {
                noOfvotes++;
            }).fail(function () {
                noOffail++;
            }).always(function () {
                noOfattempt++;
            })
        );
    }

    $.when.apply(undefined, XHR).done(function() {
        console.log('No of attempt :' + noOfattempt);
        console.log('No of vote :' + noOfvotes);
        console.log('No of fail :' + noOffail);
    });
});

答案 1 :(得分:3)

$('#vote').click(function(e) {                                      
    // some code

    var requests = [];
    for(var i = 0; i < 500; i++){
        requests.push($.ajax({ ... }));
    }
    $.when.apply($, requests).then(function() {
        console.log('No of attempt :' + noOfattempt);       
        console.log('No of vote :' + noOfvotes);
        console.log('No of fail :' + noOffail); 
    });
});

编辑请注意,.when会在所有请求完成作业或其中一个请求失败时触发。如果您想在所有请求完成后触发回调(无论是否有错误),请尝试以下操作:

var custom_when = function(reqs) {
    var def = $.Deferred(),
        counter = reqs.length;
    for (var i = 0; i < counter; i++) {
        reqs[i].always(function() {
            counter--;
            if (!counter) {
                def.resolve();
            }
        });
    }
    return def.promise();
};

并使用它:

custom_when(requests).then(...);

答案 2 :(得分:1)

将日志语句移动到.always并检查noOfattempt是否等于您尝试的数量。

.always(function() {
  noOfattempts++;
  if (noOfattempts === 500) {
    // we're done
  }
 })