setTimeout在for循环中改变最终输出;如何在不改变最终结果的情况下延迟for循环的运行 &



我正在尝试使用javascript函数在我的网站上制作自定义的打字机效果。为了在输入每个字母之间增加延迟,我为for循环的每次运行实现了交错的setTimeout,因此与前一次相比,每次迭代都会额外延迟300ms。我需要将特殊字符(' '<', '>)作为单个字符而不是单个字母输入,因此我有一些else if条件。当排除setTimeout时,这产生了预期的效果。但是,添加延迟会导致在打印出整个字符后拼写出该代码的单个字母。我该如何解决这个问题?

function type(fullTxt, current = '') {
for (let i = current.length, j = 0; i < fullTxt.length; i++, j++) {
setTimeout(function() {
if (fullTxt.substring(i, i+6) === '&nbsp;') {
console.log(fullTxt.substring(0, i+6));
i = i + 5;
} else if (fullTxt.substring(i, i+4) === '&lt;') {
console.log(fullTxt.substring(0, i+4));
i = i + 3;
} else if (fullTxt.substring(i, i+3) === '&gt') {
console.log(fullTxt.substring(0, i+3));
i = i + 2;
} else {
console.log(fullTxt.substring(0, i+1));
}
console.log(j); //included just to ensure j is counting properly
console.log(i); //included to check progress of loop
console.log(fullTxt.length); //included to check endpoint of for loop
}, j * 300);
}
}
type('hello&nbsp;');

预期输出:

// h
// 0
// 0
// 11
// he
// 1
// 1
// 11
// hel
// 2
// 2
// 11
// hell
// 3
// 3
// 11
// hello
// 4
// 4
// 11
// hello&nbsp;
// 5
// 10
// 11

现在更安全的是使用async/await,调用Promise,这样,你的循环实际上是在等待之前的一个完成。

这也使得东西更容易写,或以后修改。

超时时间设置为2000ms。

async function type(fullTxt, current = '') {
for (let i = current.length, j = 0; i < fullTxt.length; i++, j++) {
await wait(2000) // Wait for 2000ms
if (fullTxt.substring(i, i+6) === '&nbsp;') {
console.log(fullTxt.substring(0, i+6));
i = i + 5;
} else if (fullTxt.substring(i, i+4) === '&lt;') {
console.log(fullTxt.substring(0, i+4));
i = i + 3;
} else if (fullTxt.substring(i, i+3) === '&gt') {
console.log(fullTxt.substring(0, i+3));
i = i + 2;
} else {
console.log(fullTxt.substring(0, i+1));
}
console.log(j); //included just to ensure j is counting properly
console.log(i); //included to check progress of loop
console.log(fullTxt.length); //included to check endpoint of for loop       
}
}
// Generic Promise function
function wait(delayInMS) {
return new Promise((resolve) => setTimeout(resolve, delayInMS));
}
type('hello&nbsp;');

您可以将setTimeout只放在console.log上,而不是在整个if语句周围。

function type(fullTxt, current = '') {
for (let i = current.length, j = 0; i < fullTxt.length; i++, j++) {
if (fullTxt.substring(i, i + 6) === '&nbsp;') {
setTimeout(function() {
console.log(fullTxt.substring(0, i + 6));
}, j * 300);
i = i + 5;
} else if (fullTxt.substring(i, i + 4) === '&lt;') {
setTimeout(function() {
console.log(fullTxt.substring(0, i + 4));
}, j * 300);
i = i + 3;
} else if (fullTxt.substring(i, i + 3) === '&gt') {
setTimeout(function() {
console.log(fullTxt.substring(0, i + 3));
}, j * 300);
i = i + 2;
} else {
setTimeout(function() {
console.log(fullTxt.substring(0, i + 1));
}, j * 300);
}
setTimeout(function() {
console.log(j); //included just to ensure j is counting properly
console.log(i); //included to check progress of loop
console.log(fullTxt.length); //included to check endpoint of for loop
}, j * 300);
}
}
type('hello&nbsp;');

您可以使用async函数

实现这一点
async function type(fullTxt, current = '') {
for (let i = current.length, j = 0; i < fullTxt.length; i++, j++) {
await waitFor(j*300);
if (fullTxt.substring(i, i+6) === '&nbsp;') {
console.log(fullTxt.substring(0, i+6));
i = i + 5;
} else if (fullTxt.substring(i, i+4) === '&lt;') {
console.log(fullTxt.substring(0, i+4));
i = i + 3;
} else if (fullTxt.substring(i, i+3) === '&gt') {
console.log(fullTxt.substring(0, i+3));
i = i + 2;
} else {
console.log(fullTxt.substring(0, i+1));
}
console.log(j); //included just to ensure j is counting properly
console.log(i); //included to check progress of loop
console.log(fullTxt.length); //included to check endpoint of for loop
}
}


type('hello&nbsp;');

这里是waitFor函数

function waitFor(ms){
return new Promise(resolve=> setTimeout(resolve,ms))
}

最新更新