Javascript 针对具有不同持续时间的多个函数响应本机setInterval函数

Javascript 针对具有不同持续时间的多个函数响应本机setInterval函数,javascript,reactjs,react-native,Javascript,Reactjs,React Native,我在React Native组件中有两个函数,一个应该每10秒刷新一次,另一个应该每1秒刷新一次。我已经在componentDidMount()上实现了setInterval()函数来刷新componentDidMount()和componentWillUnmount()上的clearInterval(),但是我面临着麻烦,它只需要一个持续时间最短的函数。但若将两个函数的持续时间设置为相同的持续时间,则我将获得相同的结果 这是一个例子 。。。 类应用程序扩展了React.Component{ 建

我在React Native组件中有两个函数,一个应该每10秒刷新一次,另一个应该每1秒刷新一次。我已经在
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我注释掉了所有的获取和附加内容