Javascript 针对具有不同持续时间的多个函数响应本机setInterval函数
我在React Native组件中有两个函数,一个应该每10秒刷新一次,另一个应该每1秒刷新一次。我已经在Javascript 针对具有不同持续时间的多个函数响应本机setInterval函数,javascript,reactjs,react-native,Javascript,Reactjs,React Native,我在React Native组件中有两个函数,一个应该每10秒刷新一次,另一个应该每1秒刷新一次。我已经在componentDidMount()上实现了setInterval()函数来刷新componentDidMount()和componentWillUnmount()上的clearInterval(),但是我面临着麻烦,它只需要一个持续时间最短的函数。但若将两个函数的持续时间设置为相同的持续时间,则我将获得相同的结果 这是一个例子 。。。 类应用程序扩展了React.Component{ 建
componentDidMount()
上实现了setInterval()
函数来刷新componentDidMount()
和componentWillUnmount()
上的clearInterval()
,但是我面临着麻烦,它只需要一个持续时间最短的函数。但若将两个函数的持续时间设置为相同的持续时间,则我将获得相同的结果
这是一个例子
。。。
类应用程序扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
BTL级别:0,
btState:null,
};
}
componentDidMount(){
这个.getBtLevels();
这个.getBtState();
这个.batLS2();
这个。batLS10();
}
组件将卸载(){
clearInterval(()=>{this.batLSS();this.batLS10();});
}
getBtLevels=()=>{
获取(apiUrl)。然后((res)=>
this.setState({btLevel:res.level}),
);
};
getBtLevelArcs=()=>{
获取(apiUrl)。然后((res)=>
this.setState({btLevelArc:res.level}),
);
};
getBtState=()=>{
获取(apiUrl)。然后((res)=>
this.setState({BtState:res.state}),
);
};
batLS10=()=>{
设置间隔(()=>{
这个.getBtLevelArcs();
}, 10000);
};
batLS2=()=>{
设置间隔(()=>{
这个.getBtLevels();
这个.getBtState();
}, 1000);
};
...
在上面的代码中this.getBtLevels();this.getBtState();
this.getBtLevelArcs();this.getBtLevelArcs();this.getBtLevelArcs()中,每10秒提取一次值;函数得到相同的值。但是一个应该每1秒刷新一次,另一个应该每10秒刷新一次。这里我得到的是1s setInterval函数这个。batLS2()
是刷新整个组件
我该如何实现这一个刷新值1s和另一个刷新值10s
这是原始版本代码。我通过示例和语句理解的是,您希望每隔1秒调用
getBtLevels
和getBtState
,每隔10秒调用getBtLevelArcs
。
但是当getBtState
和getBtLevels
调用时,它们的setState
会更新整个组件,这在您的情况下是不可接受的
理想情况下,这不应该是一个问题,因为所有三个函数都有不同的状态。btLevel
、btLevelArc
和btState
。更新一个状态不应该影响另一个。但这完全取决于您的UI逻辑
如果这仍然是一个问题:您可以做什么。您可以将组件分为两个组件。第一个组件将保存与getBtLevels
和getBtState
相关的UI,第二个组件将包含与getBtLevelArcs
相关的UI。这是必需的,因为setState将重新呈现整个组件
代码如下所示:
class App extends React.Component {
...
//some common handlers for SubApp1 and SubApp2
...
render() {
return (
<React.Fragment>
<SubApp1 />
<SubApp2 />
</React.Fragment>
)
}
class SubApp1 extends React.Component {
constructor(props) {
super(props);
this.state = {
btLevel: 0,
btState: null,
};
}
componentDidMount() {
this.getBtLevels();
this.getBtState();
this.batLS2();
}
componentWillUnmount() {
clearInterval(() => { this.batLSS(); });
}
getBtLevels = () => {
fetch(apiUrl).then((res) =>
this.setState({ btLevel: res.level }),
);
};
getBtState = () => {
fetch(apiUrl).then((res) =>
this.setState({ BtState: res.state }),
);
};
batLS2 = () => {
setInterval(() => {
this.getBtLevels();
this.getBtState();
}, 1000);
}
...
...
class SubApp2 extends React.Component {
constructor(props) {
super(props);
this.state = {
btLevelArc: 'some default value'
};
}
componentDidMount() {
this.batLS10();
}
componentWillUnmount() {
clearInterval(() => { this.batLS10(); });
}
getBtLevels = () => {
fetch(apiUrl).then((res) =>
this.setState({ btLevel: res.level }),
);
};
getBtState = () => {
fetch(apiUrl).then((res) =>
this.setState({ BtState: res.state }),
);
};
getBtLevelArcs = () => {
fetch(apiUrl).then((res) =>
this.setState({ btLevelArc: res.level }),
);
};
...
...
类应用程序扩展了React.Component{
...
//SubApp1和SubApp2的一些常见处理程序
...
render(){
返回(
)
}
类SubApp1扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
BTL级别:0,
btState:null,
};
}
componentDidMount(){
这个.getBtLevels();
这个.getBtState();
这个.batLS2();
}
组件将卸载(){
clearInterval(()=>{this.batLSS();});
}
getBtLevels=()=>{
获取(apiUrl)。然后((res)=>
this.setState({btLevel:res.level}),
);
};
getBtState=()=>{
获取(apiUrl)。然后((res)=>
this.setState({BtState:res.state}),
);
};
batLS2=()=>{
设置间隔(()=>{
这个.getBtLevels();
这个.getBtState();
}, 1000);
}
...
...
类SubApp2扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
btLevelArc:“某些默认值”
};
}
componentDidMount(){
这个。batLS10();
}
组件将卸载(){
clearInterval(()=>{this.batLS10();});
}
getBtLevels=()=>{
获取(apiUrl)。然后((res)=>
this.setState({btLevel:res.level}),
);
};
getBtState=()=>{
获取(apiUrl)。然后((res)=>
this.setState({BtState:res.state}),
);
};
getBtLevelArcs=()=>{
获取(apiUrl)。然后((res)=>
this.setState({btLevelArc:res.level}),
);
};
...
...
问题
clearInterval
通过传递从setInterval
返回的引用来工作,即this.timerId=setInterval(…
和clearInterval(this.timerId)
我怀疑发生的情况是,您编辑代码并运行,设置了一个间隔回调(但没有清除),然后编辑并重新运行代码,设置了另一个间隔回调(再次,未清除),等等。在组件卸载时,您基本上没有清除间隔回调(如页面刷新)
解决方案
为每个间隔计时器添加一个计时器变量
constructor(props) {
super(props);
...
this.timer1 = null;
this.timer2 = null;
}
下马时清除每个间隔
componentWillUnmount() {
clearInterval(this.timer1)
clearInterval(this.timer2)
}
保存计时器引用
batLS10 = () => {
this.timer2 = setInterval(() => {
this.getBtLevelArcs();
}, 10000);
};
batLS2 = () => {
this.timer1 = setInterval(() => {
this.getBtLevels();
this.getBtState();
}, 1000);
};
clearInterval
通过传递从setInterval
返回的引用来工作,即this.timerId=setInterval(…
和clearInterval(this.timerId)
@DrewReese我很感激,但你能举个例子简单介绍一下吗。结合@shubham回答它的工作直到仍然存在相同的问题,可能是我的错误实现,我在Expo中更新了代码。@fusionweb我注释掉了所有的获取和附加内容