我遇到了一个问题,我的api调用达到了超时限制,但是继续为所提供的其余请求循环,导致控制台中的n
个超时日志数量(在这种情况下为5) 。我想要它,以便我可以按照break;
的方式执行某些操作,然后完全退出,以便不记录其余的调用。例如。如果呼叫立即超时,则只记录一个超时日志而不是当前的5个,并且不会发出五个api请求。
let qs = {
requests: 5,
timeout: 1000
};
let prices = [];
let highest = 0;
const url = 'http://somedata.com';
function xhr(qs){
return $.ajax({
url: url,
dataType: 'json',
timeout: qs.timeout,
success: function (data) {
let json = JSON.stringify(data['price']);
prices.push(json);
getHighestPrice(prices);
console.log(highest);
},
error: function(e, textstatus, message) {
if(textstatus==="timeout") {
console.error(textstatus);
} else {
console.error(textstatus);
}
}
});
}
function makeRequest(qs) {
for(let i = 0; i < qs.requests; i++) {
xhr(qs);
}
}
function getHighestPrice(arr) {
for(let i = 0; i <= arr.length; i++) {
if (arr[i] > highest) {
highest = arr[i]
}
}
return highest;
}
makeRequest(qs);
答案 0 :(得分:1)
由于它是一个回调函数,它将以异步方式执行。因此,即使您从您提供的其中一个回调中抛出错误,其余的也将在稍后或更早执行。我能想到的解决方案之一就是有一个标志,如果其中一个AJAX导致错误,该标志将被设置为true。类似的东西:
var hasError = false;
$.ajax({
error: function (e, textstatus, message) {
if (textstatus === "timeout") {
if (!hasError) console.error(textstatus);
hasError = true;
}
}
});
答案 1 :(得分:1)
您的代码会立即发出所有请求
应该注意的是,此代码将停止&#34;链接&#34;一旦$.ajax
出现任何错误,而不仅仅是超时 - 如果这不是必需的行为,那么还有一些事情要做
要仅在上一次成功时拨打电话,您可以链接$ .ajax返回的承诺
let qs = {
requests: 5,
timeout: 1000
};
let prices = [];
let highest = 0;
function xhr(qs){
return $.ajax({
url: url,
dataType: 'json',
timeout: qs.timeout,
success: function (data) {
let json = JSON.stringify(data['price']);
prices.push(json);
getHighestPrice(prices);
console.log(highest);
},
error: function(e, textstatus, message) {
if (textstatus==="timeout") {
console.error(textstatus);
} else {
console.error(textstatus);
}
}
});
}
function makeRequest(qs) {
let p = $.when();
for(let i = 0; i < qs.requests; i++) {
p = p.then(() => xhr(qs));
}
}
其他人已经指出您不需要将
qs
传递给xhr
,但是,我假设您发布的代码可能会被简化,所以没有删除{ {1}}参数
另一种选择是
qs
答案 2 :(得分:0)
使用Promise.all()可以简化此用例。如果你不能使用promises尝试从错误处理程序中抛出异常。像这样:
$.ajax({
error: function (e, textstatus, message) {
if (textstatus === "timeout") throw e
}
})
一定要抓住异常:
function makeRequest(qs) {
try {
for(let i = 0; i < qs.requests; i++) {
xhr(qs);
}
} catch (e) { // Handle error here }
}
答案 3 :(得分:0)
要获得所需的行为,您必须按顺序拨打所有电话,即您不能开始下一个电话,直到上一个电话完成为止(否则您不会知道它是否已经失败)。
您可以使用done
回调来确定是否应该进行下一次调用:
function makeRequest(i) {
xhr().done(function(){
if (i < qs.requests){
makeRequest(i+1)
}
})
}
makeRequest(0); // Kick things off here
此外,您不需要将qs
变量传递到makeRequest
或xhr
函数中。它不会在整个调用过程中发生变化,因此只需在xhr
函数中使用它而不传递它。