我有一个列表,我通过$.post
一次向PHP发送一个。我想在打电话给下一个之前等待每一个完成。我想用JS做这个,不要用PHP循环,因为我希望每个都显示返回值。
var list = ["a", "b", "c"];
for (i = 0; i < list.length; i++) {
$.post(con, {
callScript: list[i],
}, function(data, status) {
//Do stuff here with the data on success
});
}
我查看了$.when
,但却无法理清如何使用它。以下示例假定存在一定数量的函数而不是相同的函数n次。我也知道不允许异步错误。
有没有办法让它运行?
答案 0 :(得分:3)
递归是你在这里的好朋友。您可以创建一个为每个项调用自身的函数,在完成当前项的异步操作后调用下一个函数。当我们用完项目时,递归就会停止。
function postInOrder(list, index = 0) {
if (index < list.length) {
$.post(con, {
callScript: list[index],
}, function success(data, status) {
// do stuff here with the data on success
// ...
postInOrder(list, index + 1); // <-- run next script on completion
});
}
}
postInOrder(["a", "b", "c"])
以下是使用假post
方法的示例:
function postInOrder(list, index = 0) {
if (index < list.length) {
console.log(`Start: ${list[index]}`)
post(function success() {
console.log(`Finish: ${list[index]}`)
postInOrder(list, index + 1); // <-- run next script on completion
});
}
}
postInOrder(["a", "b", "c"])
function post(cb) { setTimeout(cb, 1000); }
&#13;
答案 1 :(得分:3)
您也可以将其减少到承诺队列:
list.reduce(function(prom,listEl){
return prom.then(function(){
return new Promise(function(next){
$.post(con, {
callScript: listEl,
}, function(data, status) {
//Do stuff here with the data on success
next();
});
});
});
},Promise.resolve());
(我认为包装成一个承诺不是必要的,可能有人对jquerys语法保持谨慎,可以自由编辑;)
答案 2 :(得分:0)
有一个非常广泛使用的库叫做#34; async&#34;这使得这种事情变得非常容易。以下是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']
});
如果出现错误,回调的模式将传递错误作为第一个参数,否则传递null作为第一个参数,然后传递实际返回值作为第二个参数。该模式在服务器和浏览器中的所有异步JavaScript中使用。
最后一个函数是系列完成后执行的函数。
你知道变量可以是JavaScript中的函数并构建你的队列,你也会变得棘手:
var processMe = [];
processMe.push(callScript('two'));
processMe.push(callScript('four'));
processMe.push(callScript('six'));
async.series([ processMe ],
function(err, results) {
// results is now equal to ['two', 'four', 'six']
});
function callScript(value, callback) {
// do something here
callback(null, value);
}
如果您需要将结果从一个步骤传递到另一个步骤,也可以使用waterfall。
如果它真的是多次相同的代码,请使用times运算符简单地迭代相同的函数N次:
// Pretend this is some complicated async factory
var createUser = function(id, callback) {
callback(null, {
id: 'user' + id
});
};
// generate 5 users
async.times(5, function(n, next) {
createUser(n, function(err, user) {
next(err, user);
});
}, function(err, users) {
// we should now have 5 users
});