如何使用Javascript按顺序在循环中执行AJAX调用
我在一个映射中循环,我想用每个映射值作为参数进行单独的AJAX调用,以获取一些数据并记录它。见下文。这是可行的,但我希望AJAX调用按照映射的顺序进行。因为每个调用都是异步的,所以我似乎应该使用承诺来按顺序实现执行。但我对承诺还不熟悉,不知道在这里该怎么做。我在这里的其他地方找过了,但什么也没找到。请帮忙如何使用Javascript按顺序在循环中执行AJAX调用,javascript,jquery,ajax,asynchronous,promise,Javascript,Jquery,Ajax,Asynchronous,Promise,我在一个映射中循环,我想用每个映射值作为参数进行单独的AJAX调用,以获取一些数据并记录它。见下文。这是可行的,但我希望AJAX调用按照映射的顺序进行。因为每个调用都是异步的,所以我似乎应该使用承诺来按顺序实现执行。但我对承诺还不熟悉,不知道在这里该怎么做。我在这里的其他地方找过了,但什么也没找到。请帮忙 map.forEach(function(url, key) { log(url); }); function log(url) { $.ajax({ url: u
map.forEach(function(url, key) {
log(url);
});
function log(url) {
$.ajax({
url: url,
dataType: 'json',
success: function (result) {
console.log(result.value);
console.log(result.name);
console.log(result.action);
}
});
}
由于$.ajax返回一个承诺,因此可以使用承诺链接来实现您想要的
var p = $.when();
map.forEach(function(url, key) {
p = p.then(function() {
return log(url);
});
});
function log(url) {
return $.ajax({
url: url,
dataType: 'json',
success: function (result) {
console.log(result.value);
console.log(result.name);
console.log(result.action);
}
});
}
注意:上面的代码只使用jQuery,没有本机承诺
或者使用数组的reduce函数
map.reduce(function(p, url) {
return p.then(function() {
return log(url);
});
}, $.when());
如果您可以使用ES2015+,那么就有本地承诺
map.reduce((p, url) => p.then(() => log(url)), Promise.resolve());
如果你愿意,你也可以这样做
function log(url) {
return $.ajax({
url: url,
dataType: 'json'
});
}
map.reduce((p, url) => p.then(results => log(url).then(result => results.concat(result))), Promise.resolve([]))
.then(results => {
results.forEach(result => {
console.log(result.value);
console.log(result.name);
console.log(result.action);
})
});
区别在于,一旦最后一个请求完成,所有console.log都会发生(如果任何一个请求失败,则不会发生任何console.log)到chain的承诺都应该起作用:
function ajaxPromises(urls) {
return Promise.all(urls.map(function(url) {
return $.ajax({
url: url,
dataType: 'json'
})
}))
}
用法:
ajaxPromises(['http://yoururl.com','http://yoururl.com'])
.then(function (result) {
// do something with result
})
.catch(function (error) {
// do something with error
})
如果您可以在项目中使用async/await语法,那么没有比这更简单的了:
async function log(url) {
return await
$.ajax({
url: url,
dataType: 'json',
})
.then(function(result) {
console.log(result.value);
console.log(result.name);
console.log(result.action);
});
}
async function run() {
for (var i = 0; i < map.length; i++) {
await log(map[i]);
}
}
run();
异步函数日志(url){code>
返回等待
$.ajax({
url:url,
数据类型:“json”,
})
.然后(函数(结果){
console.log(result.value);
console.log(result.name);
console.log(result.action);
});
}
异步函数run(){
对于(变量i=0;iforEach
更改为for
循环。它对于wait
的使用非常重要,因为它提供了异步log
调用的同步性(而不是forEach
和其他基于回调的循环)
UPD下面是一个演示这种方法的例子。既然$.ajax返回一个(几乎)承诺,承诺链接将是一种方式,或者
.reduce()
将它(可以说)稍微修饰一下。这很好,你能解释一下JQuery方式是如何知道何时移动到下一个调用的吗?承诺是如何工作的。。。解释得比我好could@JaromandaX它如何知道它在AJAX中成功而不是失败?我阅读了链接,但无法理解jquery ajax返回承诺成功时解决,失败时拒绝。。。您知道“解析”和“拒绝”在承诺方面意味着什么吗?async await与$相比有什么优势。when()?@user8571142$。when
是特定于jQuery的方法,与所有javascript世界无关。另外,我喜欢Jaromanda X的reduce
解决方案,但是for
+await
更具可读性。所有的魔力都隐藏在异步/等待实现下,这使得异步逻辑看起来就像是同步的。