如何在前一个数组循环后循环遍历数组?
How to loop through an array once the previous are has looped?
我正在制作一个装饰性文本,打印一个字母直到它形成一个单词,然后逐个字符删除该单词以写一个新单词。我将所有的字符串都变成了一个数组,我知道我可能需要使用 .length、.slice() 和 .join。但让我难过的一件事是,一旦前一个数组循环结束,我该如何启动下一个数组?
const skillData = {
js: [..."javascript"],
ts: [..."typescript"],
reactJS: [..."reactJS"],
html: [..."HTML5"],
css: [..."CSS3"],
reactNative: [..."React Native"],
node: [..."NodeJS"],
mongo: [..."MongoDB"],
phaser: [..."Phaser 3"],
py: [..."Python"],
};
let arrayClimber = 0;
const moveSkill = () => {
if (arrayClimber < skillData.js.length) {
arrayClimber += 1;
console.log("going up " + arrayClimber);
}
//Needs to start going down then one it reaches zero it should change to the typescript, reactJS, etc arrays
console.log(skillData.js.slice(0, arrayClimber).join(""));
};
setInterval(moveSkill, 150);
您可以尝试这样的操作:
- 使用
Object.keys
或for...in
循环对象的键
- 获取当前技能。
- 循环当前技能和打印值。您可以使用
.reduce
或正常的 for
循环
- 创建一个变量来保存要打印的字符串。由于它需要保存先前迭代的值,因此需要在此循环之外定义它。
- 每次迭代,您将当前字符添加到它并打印值。
- 在这个循环的最后,你可以截断它或者在循环之前,你可以将它初始化为默认的空。
注意: 为了防止控制台泛滥,我使用了 setTimeout
而不是 setInterval
此外,SO 对集成控制台中显示的值有限制。为了获得正确的结果,请检查实际浏览器的控制台
const skillData = {
js: [..."javascript"],
ts: [..."typescript"],
reactJS: [..."reactJS"],
html: [..."HTML5"],
css: [..."CSS3"],
reactNative: [..."React Native"],
node: [..."NodeJS"],
mongo: [..."MongoDB"],
phaser: [..."Phaser 3"],
py: [..."Python"],
};
const moveSkill = () => {
for (const key in skillData) {
const skill = skillData[key];
skill.reduce((str, char) => {
str += char;
console.log(str);
return str;
}, '')
}
};
setTimeout(moveSkill, 150);
- 将 skillData 对象更改为数组
- 使用 currentIndex 变量记录当前单词
- 创建一个 'finished' 布尔值以在数组完成迭代时停止执行 setInterval。
const skillData = [
[..."javascript"],
[..."typescript"],
[..."reactJS"],
[..."HTML5"],
[..."CSS3"],
[..."React Native"],
[..."NodeJS"],
[..."MongoDB"],
[..."Phaser 3"],
[..."Python"],
];
let arrayClimber = 0;
let currentIndex = 0;
let finished = false;
const moveSkill = () => {
if (arrayClimber < skillData[currentIndex].length) {
arrayClimber += 1;
console.log("going up " + arrayClimber);
} else {
currentIndex++;
arrayClimber = 0;
}
if (skillData.length == currentIndex) {
finished = true;
return;
}
//Needs to start going down then one it reaches zero it should change to the typescript, reactJS, etc arrays
console.log(skillData[currentIndex].slice(0, arrayClimber).join(""));
};
setInterval(() => {
if (!finished)
moveSkill();
}, 150);
只要打印了一个单词(并在您的情况下将其删除),您就需要知道一个条件。由于单词的长度不同我建议你使用promises。有了promises,你可以检查一个词的条件是否已经完全打印出来,然后履行promise。
这使您能够在开始下一个单词之前动态等待每个单词打印完毕。通过迭代器协议的组合,您可以遍历每个承诺并等待它完成,然后再开始下一个单词。
下面的示例使用 generator function 创建这样一个可迭代对象,它为需要打印的每个单词产生一个承诺。当循环此对象时,您打印每个单词,等待它完成,然后继续列表中的下一个单词。
这种方法的一个优点是您可以轻松控制每个单词的时间,并且代码是非阻塞的。所以其他脚本将 运行 而不必等待这个脚本结束。
const wordElement = document.getElementById('word');
const skillData = {
js: [..."javascript"],
ts: [..."typescript"],
reactJS: [..."reactJS"],
html: [..."HTML5"],
css: [..."CSS3"],
reactNative: [..."React Native"],
node: [..."NodeJS"],
mongo: [..."MongoDB"],
phaser: [..."Phaser 3"],
py: [..."Python"],
};
const printWord = (word, speed) => new Promise(resolve => {
let index = 1;
let wordLength = word.length;
let interval = setInterval(() => {
if (index <= wordLength) {
let partOfWord = word.slice(0, index).join('');
requestAnimationFrame(() => {
wordElement.textContent = partOfWord;
});
index++
} else {
clearInterval(interval);
resolve(word);
}
}, speed);
});
async function* wordPrinter(data) {
for (const word of Object.values(data)) {
yield printWord(word, 100);
}
}
async function printWords() {
for await (const word of wordPrinter(skillData)) {
console.log('Word printed:', word.join(''));
}
return 'Done printing';
}
printWords().then(console.log);
<p id="word"></p>
我正在制作一个装饰性文本,打印一个字母直到它形成一个单词,然后逐个字符删除该单词以写一个新单词。我将所有的字符串都变成了一个数组,我知道我可能需要使用 .length、.slice() 和 .join。但让我难过的一件事是,一旦前一个数组循环结束,我该如何启动下一个数组?
const skillData = {
js: [..."javascript"],
ts: [..."typescript"],
reactJS: [..."reactJS"],
html: [..."HTML5"],
css: [..."CSS3"],
reactNative: [..."React Native"],
node: [..."NodeJS"],
mongo: [..."MongoDB"],
phaser: [..."Phaser 3"],
py: [..."Python"],
};
let arrayClimber = 0;
const moveSkill = () => {
if (arrayClimber < skillData.js.length) {
arrayClimber += 1;
console.log("going up " + arrayClimber);
}
//Needs to start going down then one it reaches zero it should change to the typescript, reactJS, etc arrays
console.log(skillData.js.slice(0, arrayClimber).join(""));
};
setInterval(moveSkill, 150);
您可以尝试这样的操作:
- 使用
Object.keys
或for...in
循环对象的键
- 获取当前技能。
- 循环当前技能和打印值。您可以使用
.reduce
或正常的for
循环- 创建一个变量来保存要打印的字符串。由于它需要保存先前迭代的值,因此需要在此循环之外定义它。
- 每次迭代,您将当前字符添加到它并打印值。
- 在这个循环的最后,你可以截断它或者在循环之前,你可以将它初始化为默认的空。
注意: 为了防止控制台泛滥,我使用了 setTimeout
而不是 setInterval
此外,SO 对集成控制台中显示的值有限制。为了获得正确的结果,请检查实际浏览器的控制台
const skillData = {
js: [..."javascript"],
ts: [..."typescript"],
reactJS: [..."reactJS"],
html: [..."HTML5"],
css: [..."CSS3"],
reactNative: [..."React Native"],
node: [..."NodeJS"],
mongo: [..."MongoDB"],
phaser: [..."Phaser 3"],
py: [..."Python"],
};
const moveSkill = () => {
for (const key in skillData) {
const skill = skillData[key];
skill.reduce((str, char) => {
str += char;
console.log(str);
return str;
}, '')
}
};
setTimeout(moveSkill, 150);
- 将 skillData 对象更改为数组
- 使用 currentIndex 变量记录当前单词
- 创建一个 'finished' 布尔值以在数组完成迭代时停止执行 setInterval。
const skillData = [
[..."javascript"],
[..."typescript"],
[..."reactJS"],
[..."HTML5"],
[..."CSS3"],
[..."React Native"],
[..."NodeJS"],
[..."MongoDB"],
[..."Phaser 3"],
[..."Python"],
];
let arrayClimber = 0;
let currentIndex = 0;
let finished = false;
const moveSkill = () => {
if (arrayClimber < skillData[currentIndex].length) {
arrayClimber += 1;
console.log("going up " + arrayClimber);
} else {
currentIndex++;
arrayClimber = 0;
}
if (skillData.length == currentIndex) {
finished = true;
return;
}
//Needs to start going down then one it reaches zero it should change to the typescript, reactJS, etc arrays
console.log(skillData[currentIndex].slice(0, arrayClimber).join(""));
};
setInterval(() => {
if (!finished)
moveSkill();
}, 150);
只要打印了一个单词(并在您的情况下将其删除),您就需要知道一个条件。由于单词的长度不同我建议你使用promises。有了promises,你可以检查一个词的条件是否已经完全打印出来,然后履行promise。
这使您能够在开始下一个单词之前动态等待每个单词打印完毕。通过迭代器协议的组合,您可以遍历每个承诺并等待它完成,然后再开始下一个单词。
下面的示例使用 generator function 创建这样一个可迭代对象,它为需要打印的每个单词产生一个承诺。当循环此对象时,您打印每个单词,等待它完成,然后继续列表中的下一个单词。
这种方法的一个优点是您可以轻松控制每个单词的时间,并且代码是非阻塞的。所以其他脚本将 运行 而不必等待这个脚本结束。
const wordElement = document.getElementById('word');
const skillData = {
js: [..."javascript"],
ts: [..."typescript"],
reactJS: [..."reactJS"],
html: [..."HTML5"],
css: [..."CSS3"],
reactNative: [..."React Native"],
node: [..."NodeJS"],
mongo: [..."MongoDB"],
phaser: [..."Phaser 3"],
py: [..."Python"],
};
const printWord = (word, speed) => new Promise(resolve => {
let index = 1;
let wordLength = word.length;
let interval = setInterval(() => {
if (index <= wordLength) {
let partOfWord = word.slice(0, index).join('');
requestAnimationFrame(() => {
wordElement.textContent = partOfWord;
});
index++
} else {
clearInterval(interval);
resolve(word);
}
}, speed);
});
async function* wordPrinter(data) {
for (const word of Object.values(data)) {
yield printWord(word, 100);
}
}
async function printWords() {
for await (const word of wordPrinter(skillData)) {
console.log('Word printed:', word.join(''));
}
return 'Done printing';
}
printWords().then(console.log);
<p id="word"></p>