这个想法是让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
任何想法?
答案 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)