javascript - 不规则间隔的嵌套 settimeout(更复杂的方式)
问题描述
我得到了这个递归函数,里面有嵌套的 settimeout 函数。间隔应该是这样的。它们不是线性的(希望这是我需要的词,英语不是我的母语)。我什至想在这里添加更多的 settimeout 函数。我见过的解决此类问题的链接用于线性进展,例如时钟倒计时等。但我有一些不规则的间隔模式。那么有没有更好,更复杂的方法来做到这一点......这是我的代码:
function betterBlitzColor() {
$(".playerInfoCoatTwo").animate({ backgroundColor: "transparent" }, 20);
setTimeout(function () {
$(".playerInfoCoatTwo").animate({ backgroundColor: "black" }, 20)
setTimeout(function () {
$(".playerInfoCoatTwo").animate({ backgroundColor: "transparent" }, 20)
setTimeout(function () {
$(".playerInfoCoatTwo").animate({ backgroundColor: "black" }, 20)
setTimeout(function () {
$(".playerInfoCoatTwo").animate({ backgroundColor: "transparent" }, 20)
setTimeout(function () {
$(".playerInfoCoatTwo").animate({ backgroundColor: "black" }, 20)
if(myRandomNumberBetween(1, 100) > 10)
{
setTimeout(function () {
$(".playerInfoCoatTwo").animate({ backgroundColor: "transparent" }, 20)
setTimeout(function () {
$(".playerInfoCoatTwo").animate({ backgroundColor: "black" }, 20)
if(myRandomNumberBetween(1, 100) > 10)
{
setTimeout(function () {
$(".playerInfoCoatTwo").animate({ backgroundColor: "transparent" }, 20)
setTimeout(function () {
$(".playerInfoCoatTwo").animate({ backgroundColor: "black" }, 20)
setTimeout(function () {
$(".playerInfoCoatTwo").animate({ backgroundColor: "transparent" }, 20)
setTimeout(function () {
$(".playerInfoCoatTwo").animate({ backgroundColor: "black" }, 20)
setTimeout(betterBlitzColor, myRandomNumberBetween(5000, 5000)); // inside
}, 150)
}, 100)
}, 100)
}, 400) // level 3
}
else{
setTimeout(betterBlitzColor, myRandomNumberBetween(5000, 5000)); // inside
}
}, 300)
}, 650) // level 2
}
else{
setTimeout(betterBlitzColor, myRandomNumberBetween(5000, 5000)); // inside
}
}, 50)
}, 50)
}, 150)
}, 50)
}, 300)
}
我只能说这段代码看起来很奇怪。必须有一些更好的方法......我访问过的链接更像是这样解决问题:
我不知道在我的情况下我将如何使用它。一些帮助或建议?
解决方案
因为您的animate
调用总是针对同一个元素,并且集合backgroundColor
是可预测的(从透明到黑色到透明等等),所以所有这些功能都可以抽象为一个函数。为了轻松链接它,您可以让该函数返回 aPromise
在所需时间后解析,允许您使用.then
s 或await
不使用回调嵌套。此外,由于您经常连续执行许多动画(延迟后),您可以传递一个数组,其中包含每个动画之间要等待的毫秒数,并使用循环进行动画处理,然后await
在Promise
那么多毫秒后解析。
当您在长代码块和短代码块之间交替时,可以减少缩进地狱的其他方法是提前返回。也就是说,与您的if (myRandomNumberBetween(1, 100) > 10) {
测试一样,而不是
if (test1) {
// many lines 1
if (test2) {
// many lines 2
// many more lines
} else {
// do something else 1
} else {
// do something else 2
}
这很不可读 - 每个测试都do something else
连接到哪个测试?这不是立即显而易见的,这是一个问题。相反,您可以执行以下操作:
if (!test) {
// do something else 1
return;
}
// many lines 1
if (!test2) {
// do something else 2
return;
}
// many lines 2
将所有这些转换为原始代码的修复:
// Animation part:
let isBlack = true;
function animate() {
$(".playerInfoCoatTwo").animate({
backgroundColor: isBlack ? "transparent" : 'black'
}, 20);
isBlack = !isBlack;
}
// Delay function,
// allows for much flatter code when you can `await` a `Promise` compared to `setTimeout`:
const delay = ms => new Promise(res => setTimeout(res, ms));
async function animateAndWait(msArr) {
for (let i = 0; i < msArr.length; i++) {
animate();
await delay(msArr[i]);
}
}
async function betterBlitzColor() {
await animateAndWait([0, 300, 50, 150, 50, 50]);
if (myRandomNumberBetween(1, 100) <= 10) {
return delay(myRandomNumberBetween(9000, 18000))
.then(betterBlitzColor);
}
await animateAndWait([650, 300]);
if (myRandomNumberBetween(1, 100) <= 10) {
return delay(myRandomNumberBetween(9000, 18000))
.then(betterBlitzColor);
}
await animateAndWait([400, 100, 100, 150]);
delay(myRandomNumberBetween(9000, 18000))
.then(betterBlitzColor);
}
推荐阅读
- r - 在 data.frame 中获取一行作为向量,其中每个元素都是一个字符串
- c# - 将查询保存在不同的变量中
- python - 为什么我会收到此错误:“ModuleNotFoundError: No module named 'nst_utils'”
- javascript - 设置语言环境不需要修改
- html - 将具有绑定的组件移到其父级之外
- slurm - 通过 slurm 中的作业数组任务 ID 保持/释放作业的简单方法
- go - 如何在 Go SDK 中使用 Couchbase N1QL 查询扩展
- kdb - Interpreting.Qw[] 是否存在潜在问题?
- postgresql - 此 PostgreSQL 代码会产生哪些并发问题?
- javascript - HostListener 和 event.target