如何使AJAX同步(SJAX)

时间:2016-03-09 02:36:29

标签: jquery ajax

这个想法是让AJAX请求在继续执行之前等待控制器回复。这是因为我在for循环中实现了AJAX。

for (var i = 0; i <= qtg.length-1; i++) {
    index++;
    gq(type, objParams.intro + " #" + index, qtg[i]); // ajax request happens here
}

function gq(type, intro, qtg) {
    var new_question_params = "type=" + type+ "&intro=" + intro+ "&q=" + qtg;

    $.ajax({
        type: "POST",
        async: false, // async set to false doesnt do a thing
        url: "./cntlr/generate/",
        data: new_question_params,
        success: function(data, textStatus, jqXHR) {
             console.log("created order : " + (data.q.order));
        },
        dataType: "json"
    });
}

预期输出应为:

  

创建顺序:1

     

创建顺序:2

     

创建顺序:3

     

创建顺序:4

Ajax返回:

  

创建顺序:4

     

创建顺序:2

     

创建顺序:1

     

创建顺序:3

任何想法?

5 个答案:

答案 0 :(得分:4)

答案

虽然异步可能会等待AJAX​​执行,但循环中的代码仍在同时进行全部4次调用。

建议

不确定为什么要进行循环,但这是制作AJAX回调的好地方,如下所示:

var totalNumber = qtg.length;

function gq(type, intro, i) {
    var new_question_params = "type=" + type+ "&intro=" + intro+ "&q=" + qtg[i];

    $.ajax({
        type: "POST",
        async: false, // async set to false doesnt do a thing
        url: "./cntlr/generate/",
        data: new_question_params,
        success: function(data, textStatus, jqXHR) {
             console.log("created order : " + (data.q.order));
             if (i < totalNumber) 
                 gq(type, intro, i+1);
        },
        dataType: "json"
    });
}

答案 1 :(得分:1)

您可以使用.queue()按顺序返回结果

function gq(type, intro, key) {
    var new_question_params = "type=" + type+ "&intro=" + intro+ "&q=" + key;    
    // included `return` statement, to return jQuery promise object from `gq` call
    return $.ajax({
        type: "POST",
        // async: false, 
        // async set to false doesnt do a thing
        url: "./cntlr/generate/",
        data: new_question_params,
        // substituted `.then()` for `success`
        dataType: "json"
    });
}

$({}).queue("q", $.map(qtg, function(request, key) {
  return function(next) {
    ++index;
    gq(type, objParams.intro + " #" + index, request)
   .then(function(data, textStatus, jqXHR) {
     console.log("created order : " + (data.q.order));
   })
   .then(next);
  }
})).dequeue("q")

var qtg = [1, 2, 3, 4], index = 0;

function asyncFn(request, index) {
  return $.Deferred(function(dfd) {
    setTimeout(function() {
      dfd.resolve(["request: " + request, "index: " + index])
    }, Math.random() * 3000)
  })
}

$({}).queue("q", $.map(qtg, function(request, key) {
  return function(next) {
    ++index;
    return asyncFn(request, index)
      .then(function(data) {
        console.log(data);
      }).then(next)
  }

})).dequeue("q")
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>

答案 2 :(得分:1)

或者你可以做一些旧的回调式递归:

(没有错误处理的基本示例 - 您的问题也没有错误处理,所以我认为这是设计的一部分?)

function gq(type, intro, qtg, callbackOnSuccess ) {
    var new_question_params = "type=" + type+ "&intro=" + intro+ "&q=" + qtg;

    $.ajax({
        type: "POST",
        url: "./cntlr/generate/",
        async: false,
        data: new_question_params,
        success: function(data, textStatus, jqXHR) {
            console.log("created order : " + (data.q.order));
            callbackOnSuccess();
        },
        dataType: "json"
    });
}

function curryAjax( a_qtg, callbackOnTermination ) {

    if (
        ( typeof a_qtg == 'undefined' ) ||
        ( a_qtg.length <= 0 )
    ) {
        callbackOnTermination();
        return;
    }

    var car = a_qtg.shift();
    var cdr = a_qtg;
    gq(
        type,
        objParams.intro + " #" + index,
        car,
        function() {
            curryAjax(cdr, callbackOnTermination);
        }
    );
}

curryAjax( qtg, function(){ console.log('Recursion (serial sequence) complete.'); } );

许多JS程序员称回调语法不如Promise风格的控件,但它至少比Promises有一个优势 - Promises尽可能有趣 - 是一个新的知识领域,一个新的标准和思维方式包裹你的头。而且他们不是银弹 - 在我的生活中有些情况下,他们没有表达足够的商业逻辑。回调很奇怪但很有趣。少量它们是美味和可维护的。递归 - 也是^ _ ^

答案 3 :(得分:0)

您可以使用优秀而强大的async

https://github.com/caolan/async

它不会使它同步 - 你不应该,但允许你控制流量。例如,使用series

async.series([
    function(callback){
        // do some stuff ...
        callback(null, 'one');
    },
    function(callback){
        // do some more stuff ...
        callback(null, 'two');
    }
],
// optional callback
function(err, results){
    // results is now equal to ['one', 'two']
});

<强>更新

在您的情况下,您可以使用whilst

模拟循环
async.whilst(
    function () { return count < 5; },
    function (callback) {
        count++;
        setTimeout(function () {
            callback(null, count);
        }, 1000);
    },
    function (err, n) {
        // 5 seconds have passed, n = 5
    }
);

答案 4 :(得分:0)

在w3学校发现以下内容

xhttp.open("GET", "ajax_info.txt", false);

向下滚动到ASYNC = FALSE w3 school

的部分