Ajax Async False Freeze

时间:2014-07-25 15:03:46

标签: javascript jquery ajax asynchronous

当前代码

更新 我需要波纹管使用async false as as async true一些上传不会命中服务器。用户界面只需要不要使用async false冻结。或者需要一种我可以控制阙的方法?

$("#goLive" ).click(function() {
        //This is fadein Spinner only apears at end of upload?
        $('.containerFixed').fadeIn();

        var subMit = "{{$client->website}}/api/key/{{$client->apikey}}/push";

        var i = 0;

        $.each(Data, function(key, value) {

            $.ajax({
                type: 'POST',
                contentType: 'application/json',
                url: subMit,
                async : false,
                dataType: "json",
                data: JSON.stringify(Data[key]),
                success: function(){

                   i++;
                    console.log(i, Data.length);
                   if(i >= Data.length){

                       $('.containerFixed').fadeOut();
                   }
                },
                error: function(){
                    i++;
                    console.log(i, Data.length);
                    console.log('Connection Failed');

                    if(i >= Data.length){

                        $('.containerFixed').fadeOut();
                    }

                }

            });
        });

4 个答案:

答案 0 :(得分:2)

这是一个解决方案,可以在不使用async: false的情况下逐个上传,同时仍使用异步i / o,而不是通过使用promises进行同步来冻结浏览器。

您首先应该在How to return the response from an AJAX call上阅读我和Felix的回答,并确保在使用之前了解解决方案。

它不包含您手动计算事物的所有复杂逻辑,实际上依赖于承诺来为您处理并发性。它将逐一提出请求。

这是:

$( '#goLive' ).click( function() {

    var subMit = "{{$client->website}}/api/key/{{$client->apikey}}/push";
    var i = 0;

    // The initial item in the queue of actions is the fadeIn action itself, when 
    // the fade in is done we start making requests, change to $.Deferred().resolve()
    // and move the fadeIn back up if you don't want to wait for it 
    var p =  $( '.containerFixed' ).fadeIn().promise(); 

    Data.forEach( function( el, i ) {   // for each item in the data chain
        p = p.then( function() {        // after the last action is done, make a new $.ajax
            return $.ajax( {
                type        : 'POST',
                contentType : 'application/json',
                url         : subMit,
                dataType    : 'json',
                data        : JSON.stringify( el )  // you probably don't need stringify here.
            } ).then( 
                function() {
                    console.log( 'done with ', i );     // log it
                }, 
                function() { 
                    return $.Deferred().resolve();      // suppress request failure
                } 
            );
        } );

        p.then( function() {                    // when all the actions are done
            $( '.containerFixed').fadeOut();    // when all done - fade out
        } );
    } );
} );

答案 1 :(得分:1)

尝试

$("#goLive" ).click(function() {
        //This is fadein Spinner only apears at end of upload?

        var subMit = "/echo/json/";

        var i = 0;
        var Data = new Array(100);
        $.each(Data, function(key, value) {

            $.ajax({
                beforeSend : function () {
                   $(".containerFixed").fadeIn("slow");
                },
                type: 'POST',
                contentType: 'application/json',
                url: subMit,
                async : true,
                dataType: "json",
                data: JSON.stringify(Data[key]),
                success: function(){

                   i++;
                    console.log(i, Data.length);
                   if(i >= Data.length){

                       $('.containerFixed')
                       .html("loading complete...")
                       .delay(1000)
                       .fadeOut("slow");

                   }
                },
                error: function(){
                    i++;
                    console.log(i, Data.length);
                    console.log('Connection Failed');

                    if(i >= Data.length){

                        $('.containerFixed').fadeOut();
                    }

                }

            });
        });
});

jsfiddle http://jsfiddle.net/guest271314/BwVzw/

答案 2 :(得分:1)

来自jQuery #ajax documentation

  

请注意,同步请求可能会暂时锁定浏览器,并在请求处于活动状态时禁用任何操作。从jQuery 1.8开始,不推荐使用async:false和jqXHR($ .Deferred);您必须使用success / error / complete回调选项而不是jqXHR对象的相应方法,例如jqXHR.done()或不推荐使用的jqXHR.success()。

虽然您没有明确说明为什么需要这些请求同步发生,并且代码并不表示需要它,但我首先建议删除async: false选项。

但是,如果您确实需要按顺序执行这些请求,那么这里有一个代码示例,可以在不使用已弃用的async: false选项的情况下执行该操作,而是正确使用complete回调选项:

var subMit = "{{$client->website}}/api/key/{{$client->apikey}}/push";
var requestData = [];
$.each(Data, function(key, value) {
    requestData.push(JSON.stringify(Data[key]));
});

$("#goLive" ).click(sendRequests);

function sendRequests() {
    $('.containerFixed').fadeIn();

    var i = 0;

    function complete() {
        i++;
        if (i >= requestData.length) {
            $('.containerFixed').fadeOut();
        } else {
            sendRequest(i, complete);
        }
    }

    sendRequest(i, complete);
}

function sendRequest(i, complete) {
    $.ajas({
        type: 'POST',
        contentType: 'application/json',
        url: subMit,
        dataType: "json",
        data: requestData[i],
        error: function(){
            console.log('Connection Failed');
        },
        complete: complete
    });
}

我删除了async: false选项,而是手动实现了您要查找的行为。为简洁起见,我删除了一些我认为不重要的日志记录语句。我还假设Data是静态映射,因此requestData可以安全地异步引用。当然,您可以选择在requestData函数内部创建sendRequests以保护自己,并且如果您有更多特定于案例的需求,则可以区别这些函数。

答案 3 :(得分:0)

猜测$('.containerFixed').fadeIn();是异步的,它将在一组时间内逐渐显示使用超时或间隔(不确定它是如何实现的)。然后你同步ajax POST块,它只会"淡入"在帖子完成后。

您应该在success和/或error回调中完成所有工作,并将其作为异步帖子。