Как вызвать две функции в обратном вызове setInterval в хуке useEffect - PullRequest
0 голосов
/ 30 апреля 2019

Я запускаю setInterval в хуке useEffect для последовательного запуска двух функций, однако только первые функции зацикливаются.Что мне нужно сделать, чтобы запустить первую функцию, а затем вторую?

Я даже пытался запустить две функции setInterval и изменить их параметры задержки, чтобы попытаться смоделировать последовательное поведение, которое я ищу.Но это дает сбой, и совершенно очевидно, что есть проблема с моим текстовым эффектом.

   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(), но я этого не понимаюэффект.

1 Ответ

1 голос
/ 30 апреля 2019

Основная проблема заключается в том, что время задержки для стирания эффектов короче, чем самая большая задержка для отображения эффекта.Поймите, что таймауты для отображения и стирающего эффекта выполняются все за один раз, поэтому задержки должны продолжать увеличиваться, если вы хотите, чтобы обратные вызовы (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>

Возможно, вы захотите взглянуть на обещания и async функции, которые могут упростить работу с этим типом асинхронности (мнения расходятся).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...