Запуск синхронизации функций Javascript - PullRequest
0 голосов
/ 27 февраля 2019

Я пытаюсь создать программу на javascript, которая может принимать массив слов и выводить каждое слово буква за буквой на экране, а затем удалять каждую букву и переходить к следующему слову в массиве.Мне удалось заставить его работать с одним словом массива, но когда я использую два или более, они сцепляются друг с другом, как если бы они были асинхронными или параллельными.Это код:

const words_js = document.querySelector('.words-js');
const words = [
  'driven',
  'condident',
  'creative',
  'inspired',
  'productive',
  'focused',
  'fullfiling'
];

function runWords() {
  words.forEach((word, index) => {
    setTimeout(() => {
      runLetter(word, 2, 0);
    }, 1000 * (index))

  });

}

function runLetter(word, max, count) {
  count = count + 1;
  if (count > max) {
    return
  };
  [...word].forEach((letter, index) => {
    setTimeout(() => {
      if (count === 1) {
        words_js.innerHTML += letter;
      } else {
        words_js.innerHTML = word.substring(0, word.length - index);
      }
      if (index === ([...word].length - 1)) {
        runLetter(word, max, count)
      }
    }, index * 1000);
  });
}
runWords();
<span class="words-js"></span>

Спасибо всем за потраченное время!

1 Ответ

0 голосов
/ 27 февраля 2019

Как уже упоминалось в комментариях, использование setTimeout делает ваши звонки асинхронными.Кроме того, вы сталкиваетесь с проблемой определения объема, используя setTimeout в цикле.Эта проблема может быть решена путем определения вашего setTimeout с помощью IIFE .

(function (_i) {
        setTimeout(() => {
          /*** some code ***/
          }, _i * delay)
        }(i)

Другая проблема заключается в том, что ваш код не может дать вам знать, что это сделано.Таким образом, вы не можете обработать свою очередь слов.

Эта проблема может быть решена с помощью другого подхода и некоторых языковых возможностей.

Я думаю (я могу ошибаться) вы пытаетесьдобиться эффекта набранных слов.Поэтому я назову свои функции соответственно.

typeWord(word, delay cb) Берет слово и генерирует последовательность строк: например, word = "abc" => ["a", "ab", "abc", "ab", "a", ""], а затем применяет обратный вызов к каждому элементу в массиве.используя задержку подачи в качестве интервала.

Он обернут в Обещание, таким образом вы можете прикрепить обратный вызов к .then(), когда функция разрешена.

typedWords(words, delay, cb) являетсярекурсивная функция, которая принимает массив слов и передает его в typeWord функцию один за другим синхронно.Он ожидает окончания текущего слова, прежде чем продолжить.

Наконец, вы добавляете обратный вызов, чтобы фактически изменить свой div: (s) => words_js.innerHTML = s

const words_js = document.querySelector('.words-js');
const words = [
  'driven',
  'condident',
  'creative',
  'inspired',
  'productive',
  'focused',
  'fullfiling'
];
     
    function typeWord(word, delay, cb) {
      let rangeOfWordLength = [...Array(word.length * 2)]
      // Create an array of word segments 
      let seq = rangeOfWordLength.map((_, i) => (i >= word.length) ? word.slice(0, -(i + 1 - word.length)) : word.slice(0, i + 1));
      // wrap each segment in a Promise which resolved after callback
      let promises = seq.map((segment, i) => new Promise(_r => {
    		// Proper scoping
        (function(_i) {
          setTimeout(() => {
        
            cb(segment, _r);
    
          }, _i * delay)
        }(i))
    
      }));
      
      // Return a promise that only fires after all the previous promises have resolved
      return new Promise((resolve) => {
        Promise.all(promises).then(resolve)
      })
    }
    
    async function typedWords(words, delay, cb) {
      if (words.length) {
        let next = words.shift()
        await typeWord(next, delay, cb);
        return typedWords(words, delay, cb);
      }
      return true;
    }
    typedWords(words, 500, (s, next) => { words_js.innerHTML = s; next();})
<span class="words-js"></span>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...