如何在 useEffect 挂钩中的 setInterval 回调中调用两个函数
How to call two functions in a setInterval callback within the useEffect hook
我在 useEffect 挂钩中 运行ning setInterval 连续 运行 两个函数,但是,只有第一个函数循环。我需要做什么才能让第一个函数成为 运行 然后是第二个函数?
我什至尝试过使用两个 setInterval 函数 运行ning 并更改它们的延迟选项以尝试模拟我正在寻找的连续行为。但是它出现故障,很明显我的文字效果有问题。
const myText = props.text;
const textTimeout = props.textDelay;
const funTextInterval = (textTimeout * myText.length) + 200;
const [quickText, setQuickText] = useState([]);
const displayFunText = (i) => {
setTimeout(() => {
myFunction1();
}, textTimeout * i);
};
const erraseFunText = (j) => {
setTimeout(() => {
myFunction2();
}, textTimeout * j);
};
useEffect(() => {
const loop = () => {
for (let i = 0; i < myText.length + 1; i += 1) {
displayFunText(i);
}
};
const reverseLoop = () => {
for (let j = myText.length; j > 0; j -= 1) {
erraseFunText(j);
}
};
loop();
const callLoops = () => {
reverseLoop();
loop();
};
const runLoops = useInterval(() => {
callLoops();
}, funTextInterval);
return () => {
clearInterval(runLoops);
};
}, []);
我希望先是 reverseLoop()
到 运行,然后是 loop()
到 运行,但我没有得到那种效果。
主要问题是您的擦除效果超时延迟比显示效果的最长延迟短。意识到显示的超时和擦除效果是一次性执行的,所以如果你想让回调(myFunction1,myFunction2)以正确的顺序执行,延迟应该不断增加。
这是它的工作原理。评论指出我必须进行更正的地方:
// Extra code to define the functions/variables which you did not provide (ignore it):
const output = document.querySelector("div");
const myFunction1 = () => output.textContent = myText.slice(0, output.textContent.length+1);
const myFunction2 = () => output.textContent = myText.slice(0, output.textContent.length-1);
const props = { text: "This is a test", textDelay: 100 };
const useEffect = (cb) => cb();
const useState = () => [];
const useInterval = setInterval;
// END extra code
const myText = props.text;
const textTimeout = props.textDelay;
const funTextInterval = (textTimeout * myText.length * 2) + 200; // 2 times (show+hide)!
const [quickText, setQuickText] = useState([]);
const displayFunText = (i) => {
setTimeout(() => {
myFunction1();
}, textTimeout * i);
};
const erraseFunText = (j) => {
setTimeout(() => {
myFunction2();
}, textTimeout * j);
};
useEffect(() => {
const loop = () => {
for (let i = 0; i < myText.length; i += 1) { // fix end-condition
displayFunText(i);
}
};
const reverseLoop = () => {
for (let j = myText.length; j < 2*myText.length; j += 1) { // fix to produce greater values (= delays)
erraseFunText(j);
}
};
const callLoops = () => { // change order:
loop();
reverseLoop();
};
callLoops(); // instead of loop()
const runLoops = useInterval(() => {
callLoops();
}, funTextInterval);
return () => {
clearInterval(runLoops);
};
}, []);
<div id="output"></div>
您可能需要研究 promises 和 async
函数,这可能会使这种异步更容易处理(意见不同)。
我在 useEffect 挂钩中 运行ning setInterval 连续 运行 两个函数,但是,只有第一个函数循环。我需要做什么才能让第一个函数成为 运行 然后是第二个函数?
我什至尝试过使用两个 setInterval 函数 运行ning 并更改它们的延迟选项以尝试模拟我正在寻找的连续行为。但是它出现故障,很明显我的文字效果有问题。
const myText = props.text;
const textTimeout = props.textDelay;
const funTextInterval = (textTimeout * myText.length) + 200;
const [quickText, setQuickText] = useState([]);
const displayFunText = (i) => {
setTimeout(() => {
myFunction1();
}, textTimeout * i);
};
const erraseFunText = (j) => {
setTimeout(() => {
myFunction2();
}, textTimeout * j);
};
useEffect(() => {
const loop = () => {
for (let i = 0; i < myText.length + 1; i += 1) {
displayFunText(i);
}
};
const reverseLoop = () => {
for (let j = myText.length; j > 0; j -= 1) {
erraseFunText(j);
}
};
loop();
const callLoops = () => {
reverseLoop();
loop();
};
const runLoops = useInterval(() => {
callLoops();
}, funTextInterval);
return () => {
clearInterval(runLoops);
};
}, []);
我希望先是 reverseLoop()
到 运行,然后是 loop()
到 运行,但我没有得到那种效果。
主要问题是您的擦除效果超时延迟比显示效果的最长延迟短。意识到显示的超时和擦除效果是一次性执行的,所以如果你想让回调(myFunction1,myFunction2)以正确的顺序执行,延迟应该不断增加。
这是它的工作原理。评论指出我必须进行更正的地方:
// Extra code to define the functions/variables which you did not provide (ignore it):
const output = document.querySelector("div");
const myFunction1 = () => output.textContent = myText.slice(0, output.textContent.length+1);
const myFunction2 = () => output.textContent = myText.slice(0, output.textContent.length-1);
const props = { text: "This is a test", textDelay: 100 };
const useEffect = (cb) => cb();
const useState = () => [];
const useInterval = setInterval;
// END extra code
const myText = props.text;
const textTimeout = props.textDelay;
const funTextInterval = (textTimeout * myText.length * 2) + 200; // 2 times (show+hide)!
const [quickText, setQuickText] = useState([]);
const displayFunText = (i) => {
setTimeout(() => {
myFunction1();
}, textTimeout * i);
};
const erraseFunText = (j) => {
setTimeout(() => {
myFunction2();
}, textTimeout * j);
};
useEffect(() => {
const loop = () => {
for (let i = 0; i < myText.length; i += 1) { // fix end-condition
displayFunText(i);
}
};
const reverseLoop = () => {
for (let j = myText.length; j < 2*myText.length; j += 1) { // fix to produce greater values (= delays)
erraseFunText(j);
}
};
const callLoops = () => { // change order:
loop();
reverseLoop();
};
callLoops(); // instead of loop()
const runLoops = useInterval(() => {
callLoops();
}, funTextInterval);
return () => {
clearInterval(runLoops);
};
}, []);
<div id="output"></div>
您可能需要研究 promises 和 async
函数,这可能会使这种异步更容易处理(意见不同)。