Javascript 如何在for循环中停止$.ajax?
我遇到了一个问题,我的api调用达到了它的超时限制,但继续循环提供的其余请求,导致控制台中出现Javascript 如何在for循环中停止$.ajax?,javascript,jquery,ajax,Javascript,Jquery,Ajax,我遇到了一个问题,我的api调用达到了它的超时限制,但继续循环提供的其余请求,导致控制台中出现n个超时日志(在本例中为5个)。我想要它,这样我就可以沿着中断的路线做一些事情然后完全退出,这样剩余的调用就不会被记录。例如,如果调用立即超时,将只记录一个超时日志,而不是当前的5个,并且五个api请求都不会发出 let qs = { requests: 5, timeout: 1000 }; let prices = []; let highest = 0; const url =
n
个超时日志(在本例中为5个)。我想要它,这样我就可以沿着中断的路线做一些事情
然后完全退出,这样剩余的调用就不会被记录。例如,如果调用立即超时,将只记录一个超时日志,而不是当前的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);
让qs={
请求:5,
超时:1000
};
让价格=[];
设最高值=0;
常量url=http://somedata.com';
函数xhr(qs){
返回$.ajax({
url:url,
数据类型:“json”,
超时:qs.timeout,
成功:功能(数据){
让json=json.stringify(数据['price']);
prices.push(json);
获得最高价格;
console.log(最高);
},
错误:函数(e、文本状态、消息){
如果(textstatus==“超时”){
控制台错误(文本状态);
}否则{
控制台错误(文本状态);
}
}
});
}
函数makeRequest(qs){
for(设i=0;i
使用Promise.all()可以简化此用例。如果无法使用承诺,请尝试从错误处理程序引发异常。像这样:
$.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 }
}
函数生成请求(qs){
试一试{
for(设i=0;i
要获得所需的行为,您必须按顺序进行所有调用,即在前一个调用完成之前,您不能启动下一个调用(否则您将不知道它是否失败)
您可以使用done
回调来确定是否应进行下一次调用:
function makeRequest(i) {
xhr().done(function(){
if (i < qs.requests){
makeRequest(i+1)
}
})
}
makeRequest(0); // Kick things off here
函数makeRequest(i){
xhr().done(函数()){
如果(i
此外,您不需要将
qs
变量传递到makeRequest
或xhr
函数中。它在整个调用过程中不会改变,因此只需在xhr
函数中使用它,而不传递它。因为它是一个回调,所以它将异步执行。因此,即使您从提供的回调中抛出一个错误,其余的都将稍后或更早执行。我可以想到的一个解决方案是,如果某个AJAX导致错误,将设置一个标志为true。比如:
var hasError = false;
$.ajax({
error: function (e, textstatus, message) {
if (textstatus === "timeout") {
if (!hasError) console.error(textstatus);
hasError = true;
}
}
});
您的代码一次发出所有请求 应该注意的是,一旦
$中出现任何错误,此代码将停止“链接”。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));
}
}
break
不会有任何帮助,因为所有请求都会立即启动-您可能需要查看在我尝试时部分有效的中止。它会中止当前请求,但不会中止后续请求。。。这是什么意思?您的代码不尝试中止任何内容您是否理解,使用您的代码时,所有五个请求都将始终启动?这是个问题吗?您是否只想在请求1成功时发出请求2,如果请求2成功时发出请求3等等,或者您想发出5个请求,但只记录第一个超时?目前有两个答案可以做到这一点谢谢您的回复!我刚刚实现了它,但它仍然记录了5个错误。这根本没有解决这个问题。我想这是因为这是一个竞争条件。如果我在xhr(qs)
上面的循环中注销I
,1,2,3,4,5在Catch出现错误之前全部注销,您可以发布一个示例jsbin吗?Throw肯定会停止循环。不,它不会@rapta,因为所有请求都是在任何请求有机会超时之前启动的-循环在第一个请求有机会超时之前完成,在通过时调用goodqs@tim很高兴能贡献这一小部分,如果没有别的。这是否没有提供所需的行为?也许我需要做更多的工作,但是当我实现这一点时,我得到了一个success不是xhr()的函数。
。correct,success不是$.ajax返回的对象的函数。。。也许应该。完成或。然后instead@JaromandaX对的应该完成
。愚蠢的错误对不起,谢谢你纠正我。这只是使它不会记录多次。不幸的是,电话和日志仍在进行中。Jaromanda X对此解释得最好。如果第一个请求成功,而第二个请求没有成功,那么剩下的三个电话就不会打了。我还以为你是这么问的呢。“例如,如果呼叫立即超时,将只记录一个超时日志,而不是当前的5个。”请更具体、更清楚地回答您的问题。谢谢!我不知道$。当$。当()
像(但不是完全像)Promise.resolve()
-jQuery有它自己的承诺“愿景”,从Promise/a+specCool中删除一点,我会研究一下,我不知道jQuery有自己的承诺。
let qs = {
requests: 5,
timeout: 1000
};
let prices = [];
let highest = 0;
function xhr(qs){
return $.ajax({
url: url,
dataType: 'json',
timeout: qs.timeout
}).then(data => {
let json = JSON.stringify(data['price']);
prices.push(json);
getHighestPrice(prices);
console.log(highest);
});
}
function makeRequest(qs) {
let p = $.when([]);
for(let i = 0; i < qs.requests; i++) {
p = p.then(() => xhr(qs));
// or p.then(xhr); if you don't need to pass qs on to xhr function (remove qs argument in xhr as well)
}
p.then(() => {
// this is run once all have completed
}).fail(reason => {
// this is run if there's a failure anywhere
});
}