在Javascript setInterval函数中动态修改速度

问题描述 投票:2回答:3

我有一个React应用程序,需要显示一些文本,句子之间的间隔不同,一次显示一个。

所以我要做的是将所有句子放入数组中并创建一个setInterval函数:

  startShowingText() {
    let i = 0

    this.setState({
      timer: window.setInterval(() => {
        this.setState({
          sentence: SENTENCES[i]
        })

        i += 1
      }, this.state.startingDuration)
    })
  }

不幸的是,这种方法有很多缺点:

1)需要检查才能终止;

2)我无法动态修改时间,所以一旦设置了this.state.startingDuration,那将是所有句子的速度...

3)由于某些原因,如果我将window.setInterval函数分配给该状态之外的变量,则不会执行该段代码:

  startShowingText() {
    let i = 0
    console.log('here')
    const timer = window.setInterval(() => {
      this.setState({
        sentence: SENTENCES[i]
      })

      i += 1
    }, this.state.startingDuration)
    console.log('there')
  }

此代码仅用于打印:

这里

那里

不触发实际计时器。

如何改善代码并动态调整间隔?

javascript reactjs
3个回答
2
投票

您可以使用从游戏开发界借来的一种方法,在借书中,它们创建以特定刻度间隔运行的“游戏循环”。在循环中,您可以根据当前循环迭代确定是否该输出句子了。

一个粗略的例子:

const sentences = {
    "My first sentence.": 1,
    "My second sentence.": 20, 
    "My third sentence.": 25, 
    "My fourth sentence.": 40
};
const ticks = 100;
const maxLoops = 100;

const i = setInterval(writeLoop, ticks);

let loopCounter = 0;
function writeLoop() {
	
    if (loopCounter > maxLoops) {
        clearInterval(i);
    }
  
    for (sentence in sentences) {
        let targetLoop = sentences[sentence];
        if (loopCounter == targetLoop) {
    	    document.write('<div>'+sentence+'</div>');
        }
    }
  
    loopCounter = loopCounter + 1;
}

1
投票

您可以使用setTimeout和如下所示的递归函数;

class App extends React.Component {
  sentences = ["sentence1", "sentence2", "sentence3"];
  delayTime = [1000, 500, 3000];
  
  constructor(props) {
    super(props);

    this.state = {
       selected: 0,
    }
  }
  componentDidMount() {
    this.showSentence();
  }
  showSentence() {
    const { selected } = this.state;
    setTimeout(() => {
      this.setState({ selected: (selected + 1) % 3});
      this.showSentence();
    }, this.delayTime[selected])
  }
  render() {
    return (
       <div>{this.sentences[this.state.selected]}</div>
    );
  }
}

ReactDOM.render(<App/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id='app'/>

结果:句子1 -1s-> 句子2 -0.5s-> 句子3 -3s-> 句子1再次]]


0
投票

您可以递归调用setTimeout并根据当前对话框块更新速度。

© www.soinside.com 2019 - 2024. All rights reserved.