在此React Pomodoro Clock中,有一个函数countDown
。其中有一个名为three
的函数。当前,在this.setState({ init: 'break' });
中设置two
时,three
立即出现。但是,three
应等待two
完成。任何帮助将不胜感激。
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './style.css';
/*
* A simple React component
*/
const initState = {
breakLength: 5,
breakSeconds: undefined,
sessionLength: 25,
sessionSeconds: undefined,
init: 'session',
timeLeft: undefined,
timeLeftSeconds: undefined,
started: false,
intervalFunc: undefined
}
const secondsToMins = (time) => {
//let converted = Math.floor(time / 60) + ':' + ('0' + Math.floor(time % 60)).slice(-2);
let converted = ('0' + Math.floor(time / 60)).slice(-2) + ':' + ('0' + Math.floor(time % 60)).slice(-2);
//console.log('converted')
//console.log(converted)
//console.log('#######')
return converted;
}
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = initState;
this.breakDecrement = this.breakDecrement.bind(this);
this.breakIncrement = this.breakIncrement.bind(this);
this.sessionDecrement = this.sessionDecrement.bind(this);
this.sessionIncrement = this.sessionIncrement.bind(this);
this.startStop = this.startStop.bind(this);
this.reset = this.reset.bind(this);
}
componentDidMount() {
// seconds are used for the countDown()
// seconds are converted to MM:SS at every t-minus
let breakSeconds = this.state.breakLength * 60;
let sessionSeconds = this.state.sessionLength * 60;
// Initialize everything
this.setState({ breakSeconds: breakSeconds });
this.setState({ sessionSeconds: sessionSeconds });
this.setState({ timeLeftSeconds: sessionSeconds });
this.setState({ timeLeft: secondsToMins(sessionSeconds) });
}
breakDecrement() {
// decrements the breakLength and the breakSeconds
// breakLength is only a number ie. 5 (does not show seconds)
// breakSeconds is that nunber converted into seconds
let breakLength = this.state.breakLength - 1;
if (breakLength > 0 && breakLength < 61){
this.setState({ breakLength: breakLength });
let breakSeconds = breakLength * 60;
this.setState({ breakSeconds: breakSeconds });
}
}
breakIncrement() {
// same as decrement except does increment
let breakLength = this.state.breakLength + 1;
if (breakLength > 0 && breakLength < 61){
this.setState({ breakLength: breakLength });
let breakSeconds = breakLength * 60;
this.setState({ breakSeconds: breakSeconds });
}
}
sessionDecrement() {
// decrements the sessionLength and the sessionSeconds
// sessionLength is only a number ie. 25 (does not show seconds)
// sessionSeconds is that nunber converted into seconds
let sessionLength = this.state.sessionLength - 1;
if (sessionLength > 0 && sessionLength < 61){
this.setState(prevState => ({
sessionLength: prevState.sessionLength-1,
sessionSeconds: (prevState.sessionLength-1)*60,
timeLeftSeconds: (prevState.sessionLength-1)*60,
timeLeft: secondsToMins((prevState.sessionLength-1)*60)})
);
}
}
sessionIncrement() {
// same as decrement except does increment
let sessionLength = this.state.sessionLength + 1;
if (sessionLength > 0 && sessionLength < 61){
this.setState(prevState => ({
sessionLength: prevState.sessionLength+1,
sessionSeconds: (prevState.sessionLength+1)*60,
timeLeftSeconds: (prevState.sessionLength+1)*60,
timeLeft: secondsToMins((prevState.sessionLength+1)*60)})
);
}
}
startStop(id) {
// starts the countDown, which runs continuously until the start/stop button
// is pressed again, which pauses the countdown.
// the id parameter is used by countDown to play the audio beep
if(!this.state.started){
this.countDown(id);
this.setState({ started: true});
}
// pauses the countDown
if(this.state.started){
let intervalFunc = this.state.intervalFunc;
clearInterval(intervalFunc);
this.setState({ started: false});
}
}
reset() {
let intervalFunc = this.state.intervalFunc;
clearInterval(intervalFunc);
// reset state to default values
this.setState({ breakLength: 5 });
this.setState({ sessionLength: 25 });
this.setState({ init: 'session' });
this.setState({ timeLeftSeconds: 1500})
this.setState({ timeLeft: '25:00' });
}
countDown(id){
// set the function to a variable and set state to it, so the function
// can be paused with clearInterval()
var intervalFunc = setInterval(() => down(this.state.timeLeftSeconds--), 1000);
this.setState({intervalFunc: intervalFunc});
const down = (time) =>
{
const one = async () =>{
if(time > 0){
// converts seconds to MM:SS at every t-minus
this.setState({ timeLeft: secondsToMins(time)});
console.log(time);
console.log(this.state.timeLeft);
}
return;
}
//when time reaches 0 set state.init to break
// and set seconds left to break seconds
const two = async () => {
if(time == 0 && this.state.init == 'session'){
this.setState({ timeLeft: secondsToMins(time)});
let sound = document.getElementById(id).childNodes[0];
this.setState({ init: 'break' });
console.log(this.state.init)
sound.play();
this.setState({ timeLeftSeconds: this.state.breakSeconds});
}
return;
}
//when time reaches 0 set state.init to session
// and set seconds left to session seconds
const three = async () => {
if(time == 0 && this.state.init == 'break'){
this.setState({ timeLeft: secondsToMins(time)});
let sound = document.getElementById(id).childNodes[0];
this.setState({ init: 'session' });
console.log(this.state.init)
sound.play();
this.setState({ timeLeftSeconds: this.state.sessionSeconds});
}
return;
}
one().then(two).then(three);
}
}
render() {
return (
<div id="clock">
<h1 id="title">25-5 Clock</h1>
<div>
<p id="break-label">Break Length</p>
<p id="break-length">{this.state.breakLength}</p>
<button id="break-decrement" onClick={e => this.breakDecrement()}> Decrease </button>
<button id="break-increment" onClick={e => this.breakIncrement()}> Increase </button>
</div>
<div>
<p id="session-label">Session Length</p>
<p id="session-length">{this.state.sessionLength}</p>
<button id="session-decrement" onClick={e => this.sessionDecrement()}> Decrease </button>
<button id="session-increment" onClick={e => this.sessionIncrement()}> Increase </button>
</div>
<hr/>
<div>
<p id="timer-label">{this.state.init}</p>
<p id="time-left">{this.state.timeLeft}</p>
<button id="start_stop" onClick={e => this.startStop(e.target.id)}><audio id="beep" src='./beep.mp3'></audio> start/stop </button>
<button id="reset" onClick={e => this.reset()}> reset </button>
</div>
</div>
);
}
};
/*
* Render the above component into the div#app
*/
ReactDOM.render(<Clock />, document.getElementById("app"));
index.html:
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>25-5 Clock</title>
<style>
</style>
</head>
<body>
<main>
<div id="app"></app>
</main>
</body>
</html>
答案 0 :(得分:2)
您需要使它们异步。
喜欢...
const one = async () => {
//some code
return
}
const two = async () => {
//some code
return
}
const three = async () => {
//some code
return
}
那你就可以...
one().then(two).then(three)
答案 1 :(得分:0)
您可以通过使函数返回Promise
并使用async / await
关键字来等待它们完成,然后再开始下一个,来做到这一点。
const setDelay = delay => new Promise(resolve => {
console.log(`Process running for ${delay}`);
setTimeout(() => {
console.log('Process done');
resolve();
}, delay);
});
(async () => {
await setDelay(2000);
await setDelay(3000);
await setDelay(1000);
})();
或者您可以不用async / await
并兑现承诺。
const setDelay = delay => new Promise(resolve => {
console.log(`Process running for ${delay}`);
setTimeout(() => {
console.log('Process done');
resolve();
}, delay);
});
setDelay(3000)
.then(() => setDelay(1000))
.then(() => setDelay(4000));
或者只使用良好的'ol风格的回调。但我会选择上述之一。
答案 2 :(得分:0)
解决方案:
使用数组保存状态和持续时间:
const states = [ { name: 'session', duration: 1500 }, { name: 'break', duration: 300 } ]
替换数组的索引以在会话和中断之间交替。
countDown(id){
// set the function to a variable and set state to it, so the function
// can be paused with clearInterval()
var intervalFunc = setInterval(() => down(this.state.timeLeftSeconds--), 1000);
this.setState({intervalFunc: intervalFunc});
const down = (time) =>
{
if(time > 0){
// converts seconds to MM:SS at every t-minus
this.setState({ timeLeft: secondsToMins(time)});
console.log(time);
console.log(this.state.timeLeft);
}
if (time <= 0) {
this.setState({ timeLeft: secondsToMins(time)});
let sound = document.getElementById(id).childNodes[0];
sound.play();
let stateIndex = (this.state.stateIndex + 1) % states.length;
this.setState({ stateIndex: stateIndex});
this.setState({ timeLeftSeconds: states[stateIndex].duration});
this.setState({ init: states[stateIndex].name});
console.log(this.state.init);
}
}
}