所以我想在jquery中做一个延迟的ajax请求,直到我收到一个特定的服务器响应(非null)。我该怎么做呢?
while (data.response != null) {
$.ajax(..).done(function(data);
}
function doUntilResult() {
Server.doA().done(function(data) {
Server.doB(data).done(function(result) {
//if result == null, repeat again
});
});
}
答案 0 :(得分:2)
你不能在Javascript中这样循环。 Javascript是一个事件驱动的系统。当你像这样循环时,没有其他事件可以被处理。因此,即使您的第一个Ajax调用也不会被处理。实际上,当客户端试图同时进行数百万次ajax调用时,你可能会因耗尽一些资源而将JS引擎驱动到地面。
相反,您可以异步使用ajax结果,然后根据结果决定是否再次调用它:
function poll() {
$.ajax(...).then(function(data) {
if (!data.xxxx) {
// call it again after some short delay
setTimeout(poll, 1000);
} else {
// got the result we wanted, process it
}
})
}
// start the polling
poll();
如果你想让整件事都回复承诺,你可以这样做:
function delay(t) {
return new $.Deferred(function(def) {
setTimeout(def.resolve, t);
}).promise();
}
function poll() {
return $.ajax(...).then(function(data) {
if (!data.xxxx) {
// call it again after some short delay
return delay(1000).then(poll);
} else {
// got the result we wanted, process it
return someValue;
}
})
}
// start the polling
poll().then(function(result) {
// process result here
});
P.S。尽可能快地不断地轮询某个服务器绝对不是正确的事情。如果您只有几个用户,这可能会正常工作,但只要您拥有大量用户,所有这一切都会使您的服务器无法在大多数情况下使用空轮询请求,而无法返回客户端。这是处理负载的噩梦。找到一个不轮询的架构会更好,但是如果要进行轮询,那么至少要使用某种计时器在未来的某个时间进行轮询,而不是尽可能快地进行轮询。
P.P.S。如果您真的只是等待服务器上的某些值更改,那么您可能应该使用webSocket连接。这样,客户端建立与服务器的连接并且连接仍然存在,然后在将来的任何时候,服务器都可以简单地向客户端发送消息。客户端根本不需要轮询。这可以在您的服务器基础架构上大大提高效率,并可以提供更及时的结果。
答案 1 :(得分:0)
为了给予大量控制,请写doUntilResult()
接受:
doThis
回调函数,用于确定要执行的操作以及重试/终止条件。function doUntilResult(doThis, t) {
function delay() {
return $.Deferred(function(dfrd) {
window.setTimeout(dfrd.resolve, t);
});
}
function poll() {
return $.when(doThis()).then(function(data) { // $.when() caters for non-async functions to be passed.
return (data === null) ? delay().then(poll) : data; // continue on null, otherwise return data.
});
}
return poll();
}
现在,你有一个通用的doUntilResult()
功能,可以改变你的想法,直到"没有重写。在呼叫(或呼叫)中指定了所有内容。
对于原始问题,请致电如下:
doUntilResult(function() {
return $.ajax(..).then(function(data) {
return data || null; // adjust as required to ensure that `null` is returned only for the "continue" condition.
});
}, 1000); // 1 second delay between calls
对于编辑过的问题,请致电如下:
doUntilResult(function() {
return Server.doA().then(function(data) {
return Server.doB(data);
}).then(function(result) {
return result || null; // adjust as required ...
});
}, 1000); // 1 second delay between calls
无论您想做什么,始终确保回调的.then链终止于每当轮询继续时返回null
的函数。
Here's a simple demo生成0-10的随机数; 9或更大的数字被视为数据; 9岁以下将重新尝试。 (监视控制台的进度)。