繁体   English   中英

如何在for ...循环中使用setTimeout

[英]How to Use setTimeout in a for…loop

我想要的是(新闻自动收录机类型功能):

  1. 从ul标签获取li的列表
  2. 遍历所有li并获取文本
  3. 通过firefox console.log()在控制台中显示文本
  4. 得到下一个李,重复直到显示所有李

那是目标,但是setTimeout并没有按照我的预期运行。 仅显示LAST迭代(“后四”)。 那个(“第四后”)连续显示四次。

<body>
<ul id="post_list">
 <li>Post One</li>
 <li>Post Two</li>
 <li>Post Three</li>
 <li>Post Four</li>
</ul>

<script type="text/javascript">
var ul = document.getElementById('post_list');
var li = ul.getElementsByTagName('li');

for(var x=0; x < li.length; x++){
    var li_text = li[x].childNodes[0].nodeValue;
    setTimeout(function(){showText(li_text)}, 1000);
}

function showText(text) {
    console.log(text);
}           
</script>
</body>

发生这种情况的原因是由于关闭。 for循环块周围有闭包,因此当您引用“ li_text”时,它始终等于li_text设置为的最后一个值。 for循环不会为循环的每次迭代创建单独的闭包。

正如Greg所提到的,问题在于闭包仅评估一次。 没有人为此发布解决方案,所以这里是一个。 这使用添加每次生成回调函数的函数:

加:

function getShowTextCallback(text) {
    return function(){showText(text)}
}

然后像这样在循环中使用它:

for(var x=0; x < li.length; x++){
    var li_text = li[x].childNodes[0].nodeValue;
    setTimeout(getShowTextCallback(li_text), 1000);
}

更改此:

for(var x=0; x < li.length; x++){
    var li_text = li[x].childNodes[0].nodeValue;
    setTimeout(function(){showText(li_text)}, 1000);
}

至:

for(var x=0; x < li.length; x++) (function() {
    var li_text = li[x].childNodes[0].nodeValue;
    setTimeout(function(){showText(li_text)}, x * 1000);
})()

我们如何稍微移动一些代码呢...取出关闭问题...

var ul = document.getElementById('post_list');
var li = ul.getElementsByTagName('li');

for (var x = 0, xl = li.length; x < xl; x++) {
    var li_text = li[x].innerText || li[x].textContent; // does IE support textContent??
    showText(li_text, x * 1000);
}

function showText(text, delay) {
    setTimeout(function() {
        console.log(text);
    }, delay);
}

我假设您想要的延迟是连续的(因此循环)。 因为setTimeout没有阻塞,所以您将需要在函数上进行回调以调用下一个setTimeout,或者您需要使用新的延迟专门增加每个函数的调用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM