使用setInterval()进行简单的连续轮询

问题描述 投票:0回答:5

对于需要按设定的时间间隔刷新向用户呈现的部分数据的简单 Web 应用程序,仅使用

setInterval()
从端点获取 JSON 而不是使用适当的轮询框架是否有任何缺点?

举个例子,假设我每 5 秒刷新一次处理作业的状态。

javascript ajax setinterval polling
5个回答
97
投票

我会使用

setTimeout
[文档],并始终在收到之前的响应时调用它。这样,您可以避免可能的拥塞或函数堆栈或任何您想要调用的内容,以防请求/响应花费的时间超过您的时间间隔。

所以像这样:

function refresh() {
    // make Ajax call here, inside the callback call:
    setTimeout(refresh, 5000);
    // ...
}

// initial call, or just call refresh directly
setTimeout(refresh, 5000);

21
投票

可以在最近的浏览器中使用 Promises 实现简单的非阻塞轮询功能:

var sleep = duration => new Promise(resolve => setTimeout(resolve, duration))
var poll = (promiseFn, duration) => promiseFn().then(
             sleep(duration).then(() => poll(promiseFn, duration)))

// Greet the World every second
poll(() => new Promise(() => console.log('Hello World!')), 1000)

6
投票

你可以这样做:

var i = 0, loop_length = 50, loop_speed = 100;

function loop(){
    i+= 1; 
    /* Here is your code. Balabala...*/
    if (i===loop_length) clearInterval(handler);
}

var handler = setInterval(loop, loop_speed);

1
投票

我知道这是一个老问题,但我偶然发现了它,并且以 StackOverflow 的方式做事,我认为我可以改进它。您可能需要考虑类似于“此处描述的内容”的解决方案,称为长轮询。或者另一个解决方案是 WebSockets(WebSockets 的更好实现之一,其主要目标是在所有浏览器上工作)socket.io 第一个解决方案基本上概括为您发送一个 AJAX 请求并在发送另一个请求之前等待响应,然后一旦响应已交付,就对下一个查询进行排队。

同时,在后端,直到状态发生变化才返回响应。因此,在您的场景中,您将使用一个 while 循环,该循环将持续到状态更改为止,然后将更改后的状态返回到页面。我真的很喜欢这个解决方案。正如上面链接的答案所示,这就是 facebook 所做的(或至少过去做过的)。

socket.io 基本上是 Websockets 的 jQuery,因此无论您的用户使用哪个浏览器,您都可以建立一个套接字连接,将数据推送到页面(根本不需要轮询)。这更接近黑莓的即时通知,如果您想要即时通知,这是最好的解决方案。


1
投票
@bschlueter的答案

,是的,你可以通过调用cancelCallback()

取消这个投票功能

let cancelCallback = () => {}; var sleep = (period) => { return new Promise((resolve) => { cancelCallback = () => { console.log("Canceling..."); // send cancel message... return resolve('Canceled'); } setTimeout(() => { resolve("tick"); }, period) }) } var poll = (promiseFn, period, timeout) => promiseFn().then(() => { let asleep = async(period) => { let respond = await sleep(period); // if you need to do something as soon as sleep finished console.log("sleep just finished, do something..."); return respond; } // just check if cancelCallback is empty function, // if yes, set a time out to run cancelCallback() if (cancelCallback.toString() === "() => {}") { console.log("set timout to run cancelCallback()") setTimeout(() => { cancelCallback() }, timeout); } asleep(period).then((respond) => { // check if sleep canceled, if not, continue to poll if (respond !== 'Canceled') { poll(promiseFn, period); } else { console.log(respond); } }) // do something1... console.log("do something1..."); }) poll(() => new Promise((resolve) => { console.log('Hello World!'); resolve(); //you need resolve to jump into .then() }), 3000, 10000); // do something2... console.log("do something2....")

© www.soinside.com 2019 - 2024. All rights reserved.