您不会在浏览器中执行同步 ajax(从技术上讲,在某些情况下您可以,但这样做真的很糟糕,因为它会在 ajax 调用期间锁定浏览器)。
相反,您重新设计了循环,使其仅在前一个完成时执行下一个 ajax 调用,这意味着您必须手动循环,您不能使用 for 循环。由于您的代码是伪代码(您没有显示真正的 ajax 操作),我将使用 jQuery ajax 示例,但您可以替换您拥有的任何 ajax 函数,只要它返回一个承诺或使用回调完成时发出信号。
一般的想法是,您为 ajax 调用创建一个函数,然后使用该函数的完成回调来增加索引,然后运行循环的下一次迭代。
function runLoop(data) {
var i = 0;
function next() {
if (i < data.length) {
return $.ajax(data[i]).then(function(data) {
++i;
return next();
});
else {
// all done with loop
}
}
return next();
}
// call it like this
runLoop(someArray).then(function() {
// all done here
});
如果你没有数据数组,但只想要一个循环索引:
function runLoop(limitVar) {
var i = 0;
function next() {
if (i < limitVar) {
return $.ajax(something_with_i_in_it).then(function(data) {
++i;
return next();
});
else {
// all done with loop
}
}
return next();
}
// call it like this
runLoop(theLimit).then(function() {
// all done here
});
如果你的 limitVar 不大,并且没有其他逻辑参与决定是否继续循环,如果你有一个返回 promise 的 ajax 函数,你也可以使用更简单的模式:
function runLoop(limitVar) {
var p = Promise.resolve();
for (var i = 0; i < limitVar; i++) {
p = p.then(function(prevResult) {
return someAjax(i);
});
}
return p;
}
// call it like this
runLoop(theLimit).then(function() {
// all done here
});
如果您不使用返回 Promise 的 ajax 函数,那么只需几行代码就可以将您的函数包装成这样的函数,然后您就可以更轻松地使用这些设计模式。