Как уже упоминалось в комментариях, использование 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>