在while循环中延迟

所以我想在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 }); }); } 

要给予大量控制,请编写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

这是一个简单的演示 ,它生成0-10的随机数; 9或更大的数字被视为数据; 9岁以下将重新尝试。 (监视控制台的进度)。

你不能在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 }); 

PS尽可能快地不断地轮询某个服务器,这绝对不是正确的事情。 如果您只有几个用户,这可能会正常工作,但是只要您拥有大量用户,所有这一切都会使您的服务器无法使用空轮询请求,而大部分时间都无法返回客户端。 这是处理负载的噩梦。 找到一个不轮询的架构会更好,但是如果要进行轮询,那么至少要使用某种计时器在未来的某个时间进行轮询,而不是尽可能快地进行轮询。

PPS如果您真的只是等待服务器上的某些值更改,那么您可能应该使用webSocket连接。 这样,客户端建立与服务器的连接并且连接仍然存在,然后在将来的任何时候,服务器都可以简单地向客户端发送消息。 客户端根本不需要轮询。 这可以在您的服务器基础架构上大大提高效率,并可以提供更及时的结果。