【问题标题】:How to run a timer in React component for 60 seconds and call a Redux action every 5 seconds如何在 React 组件中运行一个计时器 60 秒并每 5 秒调用一次 Redux 操作
【发布时间】:2018-09-10 19:39:49
【问题描述】:

我有一个反应容器,我想在其中运行一个计时器 60 秒,每 5 秒我想调度一个动作。此操作正在调用 api 并返回一些结果。 要处理的另一件事是假设我的操作在第 3 次调用(即 15 秒后)返回错误,那么此后我该如何停止计时器。

handleSimulateButton = (e) => {
    /*
        Once I click on Simulate button, I want the below codes to run 
        exactly for 60 seconds
    */

    function runFor60seconds(){
        /*anyRequestFails takes boolean value and I can easily determine 
          its value.
        */
        if(anyRequestFails){
            //stop timer and exit from function
        }

        // I want to this every 5 secs
        else{
            //Calculations
            let params = calculatedvalue
            this.props.callAPI(params)
        }
    }
}

我怎样才能做到这一点?我正在学习 React 和 redux,但无法弄清楚。上面的代码 sn -p 只是我所需代码的伪代码。

【问题讨论】:

  • 您可以使用 setInterval 创建计时器
  • 我阅读了它,并弄清楚了如何每 5 秒运行一次特定任务。但是如何在 60 秒后停止呢?
  • 使用 clearinterval 停止计时器
  • 我编码并且工作正常。谢谢

标签: javascript reactjs redux


【解决方案1】:

要在 JavaScript 中使用计时器,您可以使用:

setInterval();

在这种情况下,您希望将间隔分配给一个变量,以便您可以像这样取消它;

var minute = 60000;
var myInterval = setInterval(function(){ ... }, minute);

clearInterval(myInterval);

为了跟踪失败的请求,您需要在调用您的 api 的函数范围之外分配一个变量;

var failedAmount = 0;

function apiRequest(){ 
    if(failedAmount === 3) clearInterval(myInterval);
    ... 
    onFail = () => failedAmount++;
};

有关间隔的更多信息,请参阅: Intervals

【讨论】:

    【解决方案2】:

    Window.setInterval() 可用于创建间隔。

    Window.clearInterval() 可用于清除间隔。

    // Eg.
    class Eg extends React.Component {
      
      // Single interval.
      singleInterval = () => {
        
        // Prevent duplicates.
        clearInterval(this.interval)
        
        // Set timeout.
        const fiveSeconds = 1000 * 5
        this.timeout = new Date()*1 + fiveSeconds
        
        // Create Interval.
        this.interval = setInterval(() => {
        
          // Interval logic ..
          console.log('Single Interval: 1 second ..')
          
          
          if (new Date() > this.timeout) {
    
            // Interval complete.
            console.log('Interval complete.')
    
            // Tidy up.
            clearInterval(this.interval)
    
          }
    
        }, 1000)
      }
      
      // Concurrent interval.
      concurrentInterval = () => {
      
        // Set timeout.
        const fiveSeconds = 1000 * 5
        const timeout = new Date()*1 + fiveSeconds
        
        // Create Interval.
        const ID = setInterval(() => {
        
          // Interval logic ..
          console.log(`Interval ${ID}`)
          
          
          if (new Date() > timeout) {
    
            // Interval complete.
            console.log(`${ID} complete.`)
    
            // Tidy up.
            clearInterval(ID)
    
          }
    
        }, 1000)
        
      }
      
      // Render.
      render = () => (
        <React.Fragment>
          <button onClick={this.singleInterval}>Single Interval</button>
          <button onClick={this.concurrentInterval}>Concurrent Interval</button>
        </React.Fragment>
      )
    }
    
    // Mount.
    ReactDOM.render(<Eg/>, document.querySelector('#root'))
    <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <div id="root"></div>

    【讨论】:

    • // Prevent dupes clearInterval(this.interval) 你能解释一下为什么需要这样做吗?
    • 没有那行;如果start buttonspammed:您将有很多并发intervals 而没有referenceclear 它们(严重的内存泄漏)。我将comment 更改为“重复”以使代码更清晰。
    • 好的!但是假设发生这种情况,那么我们总是可以获取当前间隔的 Id 并使用该 id 来清除该间隔。我说的对吗?
    • 正确。如果你想同时运行intervals,我可以调整我的答案。
    • 是的。 Interval 内容被执行 asynchronously.
    猜你喜欢
    • 2011-03-09
    • 1970-01-01
    • 2011-03-20
    • 2014-04-24
    • 2015-04-28
    • 1970-01-01
    • 2011-08-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多