我在这里努力寻找正确的解决方案。当前,我正在使用setInterval()
“轮询”服务器并检索对象数组。要获取数据,我正在使用axios
。以下是相关功能:
componentDidMount(){
this.timer = setInterval(() => [this.getData(), this.getCustData()], 1000);
}
componentWillUnmount(){
this.timer && clearInterval(this.timer);
this.timer = false
}
getData = () => {
axios.get('http://localhost:3001/api/v1/pickup_deliveries')
.then((response) => {
this.setState({
apiData: response.data
})
})
.catch((error)=>{console.log(error);});
}
getCustData = () => {
axios.get('http://localhost:3001/api/v1/customers')
.then((response) => {
this.setState({
custData: response.data
})
})
.catch((error)=>{console.log(error);});
}
该应用程序运行如此缓慢且经常运行,它会完全挂起服务器,从而使整个应用程序无法使用。目前,它正在获取的数组有1000多个对象,并且这个数量每天都在增长。如果我在不轮询服务器的情况下获取数据,那么我的应用程序将是白天和黑夜。我不太确定答案是什么,但我知道我在做什么不是正确的方法。
这仅仅是用setInterval()
模拟“轮询”的本质,它是什么吗?还是只有在state
更改后才可以获取数据?
如果我需要实现SSE或WebSocket,我会遇到麻烦,但是我想看看是否有一种方法可以修复当前代码以提高性能。
感谢您听到我的声音。
在前端,我的建议是不要使用setInterval,而应使用setTimeout。
使用setInterval,即使对先前请求的响应尚未返回(例如:花费了超过1秒的时间),您的应用也可能会发送另一个请求。最好只在收到前一个响应后1秒钟发送另一个请求。
componentDidMount() {
getData();
}
getData = () => {
fetch().then(() => {
updateState();
// schedule next request
setTimeout(getData, 1000);
});
}
您还应该尝试减少前端需要完成的更新数量,例如,通过减少数据数量。
但是,我认为最重要的是重新考虑应用程序的设计。轮询只会变得更大的巨大JSON并不是可伸缩的设计。对服务器和客户端都不利。
如果要在服务器端进行任何更改的情况下通知客户端,则应调查WebSocket。一个简单的想法是,浏览器应建立与服务器的WS连接。在对服务器进行任何更新时,服务器应仅将更新发送给客户端,而不是向下发送全部数据。然后,客户端将更新其自己的状态。
例如,假设有2位用户正在打开同一页面,而一位用户则通过添加新产品来进行更改。服务器将收到此请求并相应地更新数据库。它还将向所有打开的WebSocket连接(添加该产品的一个连接除外)广播一条消息,其中包含一个简单的对象,如下所示:
{
"action": "INSERT",
"payload": {
"product": {
"id": 123123,
... // other product data
}
}
}
其他用户将使用此数据来更新其自己的状态,以便与服务器匹配。