对于一个简单的 Web 应用程序,需要以一定的时间间隔刷新向用户展示的部分数据,仅使用 setInterval()
从端点获取 JSON 数据而不使用适当的轮询框架是否存在任何缺点?
举例来说,假设我每 5 秒钟刷新一次处理作业状态。
对于一个简单的 Web 应用程序,需要以一定的时间间隔刷新向用户展示的部分数据,仅使用 setInterval()
从端点获取 JSON 数据而不使用适当的轮询框架是否存在任何缺点?
举例来说,假设我每 5 秒钟刷新一次处理作业状态。
根据我的评论:
我会使用setTimeout
[文档],并在每次收到上一响应后调用它。这样,如果请求/响应需要比您的间隔时间更长,就可以避免可能出现的拥塞或函数堆叠等问题。
代码如下:
function refresh() {
// make Ajax call here, inside the callback call:
setTimeout(refresh, 5000);
// ...
}
// initial call, or just call refresh directly
setTimeout(refresh, 5000);
setInterval
是个好主意:http://weblogs.asp.net/bleroy/archive/2009/05/14/setinterval-is-moderately-evil.aspx - Dave WardsetTimeout(refresh, 5000);
吗?我的意思是在初始调用之后再在被调用的函数中再次使用它? - Davidrefresh
时,超时时间已经“完成”了。没有什么需要清除的。 - Felix Kling最近的浏览器可以使用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)
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);
只需修改@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....")
setTimeout
,并在前一个响应接收后总是调用它。这样可以避免可能出现的拥堵或函数堆积等问题。 - Felix Kling