Javascript 具有动态持续时间的setTimeout函数
我有一个setTimeout函数,可以迭代值:Javascript 具有动态持续时间的setTimeout函数,javascript,Javascript,我有一个setTimeout函数,可以迭代值: var content=['1','2','3','4','5'] 风险值持续时间=['10000','10000','20000','10000','30000'] 对于(i=0;i
var content=['1','2','3','4','5']
风险值持续时间=['10000','10000','20000','10000','30000']
对于(i=0;i }
代码的问题是for循环在不等待setTimeout完成的情况下进行迭代。我建议像这样使用一点递归
var content=['1','2','3','4','5'];
风险值持续时间=['10000'、'10000'、'20000'、'10000'、'30000'];
var i=0;
var循环=函数(){
setTimeout(函数(){
if(++i }
正如另一张海报所提到的,您可能希望每个超时从最后一个超时的末尾开始。您可以使用建议的“递归”方法,但承诺将产生更可读的代码。首先,我们将编写一个wait
例程,该例程返回一个承诺,该承诺在若干毫秒内解析:
function wait(n) {
return new Promise(function(resolve) { setTimeout( resolve, n); });
}
现在,我们可以按如下方式重写您的循环:
var promise = Promise.resolve();
for (i = 0; i < content.length; i++) {
promise = promise . then(function() { return wait(duration[i]; });
}
如果你不知道如何减少,这是很值得学习的
但是想象一下,如果跳过所有这些,简单地做一些事情,而不是设置超时,就在那里等待,那该有多好。事实证明,使用async
函数实际上可以做到这一点:
async function wait_series(duration) {
^^^^^
for (i = 0; i < content.length; i++) {
await wait(duration[i]);
^^^^^
}
}
使用异步函数或其基于co
的等效函数的优点是,您可以像以前那样为循环编写常规的。它们本质上允许您以同步思维编写异步代码。你不再需要考虑承诺(尽管co
使用承诺在幕后发挥了神奇的作用)
你可能会说,写一系列连续的超时似乎需要学习很多东西。但实际上,承诺和异步函数最终比编写超时(调用函数然后设置其他超时)更容易
递归解
如果您喜欢递归解决方案,这里有一个稍微简化的版本,它实际上也可以工作(通过在最后通过()
第一次调用循环
):
“然而,持续时间不是动态的。”你能详细说明一下吗?显然,您正在将不同的值传递给setTimeout
(至少其中一些值是这样的)。我相对确信JS会自动将它们转换为数字,但是的,这些应该是数字。我将您的示例代码转换为可运行的代码段。在Chrome中,它对我来说很好(等待30秒,直到最后一个警报对话框出现)。不要将字符串传递给超时。“这不起作用”也许你只是对代码正在执行的操作有错误的期望。但由于你还没有解释你期望的行为,我们无法真正帮助你。如果代码不符合您的要求,您可能只是编写了错误的解决方案。虽然允许OP没有明确说明,并且给出了一个糟糕的标题,但拒绝做出明显的(?)假设似乎有点天真,即意图是超时应按顺序运行,或者至少发布一条评论,询问情况是否如此。我不明白为什么这个问题应该被关闭或否决;它包含了讨论异步性的好材料。如果SO的目标是帮助人们解决他们的问题,那么帮助他们澄清和构建他们的问题,包括建议他们可能缺少的内容,无疑是其中一个有价值的方面。为什么(在原始代码中)需要“等待setTimeout完成”?原始代码工作正常。但是谁第一次调用loop
呢?@GregHewgill,因为这可能是OP的意图,这是一个完全合理的,而且很可能是正确的假设,尽管正确的协议可能是在回应之前在评论中澄清这一点。OP明确表示,原始代码并没有“很好地工作”,尽管他承认他没有很好地解释它不工作的确切方式或他想要什么。因此,在这种情况下,我们能帮助他澄清他的问题陈述,而不是投票让他被遗忘吗?@torazaburo:事实上,OP没有解释代码实际应该做什么。(为了记录在案,我没有投反对票,而是试图帮助改进这个问题。)谢谢你详细、周到的回答。我将在几分钟内尝试您的一个或多个解决方案,并让您知道其进展情况。另外,感谢您的时间和努力,并提供了有益的反馈。
async function wait_series(duration) {
^^^^^
for (i = 0; i < content.length; i++) {
await wait(duration[i]);
^^^^^
}
}
function wait_series(duration) {
co(function *() {
^^
for (i = 0; i < content.length; i++) {
yield wait(duration[i]);
^^^^^
}
});
}
function wait_series(duration) {
var i = duration.length;
(function loop() {
if (i--) setTimeout(loop, duration[i]);
})();
^^
}