for循环 嵌套延时器 实例及解决方案

for循环 嵌套延时器 实例及解决方案

首先         看一个经典的for循环嵌套延时器的案例

for(var i = 0;i<lg;i++){// lg = 6
        setTimeout(function(){
            console.log(i); //此时输出为 6 个 6
        },1000)
    }

我们想要的结果是在for循环中一次打印出 i 的 值。即0,1,2,3,4,5;但是输出6个相同的个数字是什么原因呢?

这主传进去要是因为setTimeout的执行时异步执行的,而for循环的执行却非常的快,所以,在1s后执行定时器函数时, i  已经 循环到了最大值6,其他的i值已经被销毁,此时再执行定时器,则是把 i=6传进去了,所以造成了这样的结果。

那我们应该怎么解决这个问题呢?

解决这个问题首先是要解决 i 值的变量销毁问题,即浏览器的垃圾回收机制:

第一种方法:将延时器中的函数用一个自执行函数包起来,把每个循环中的 i 在被回收之前直接传入到自执行函数中,这样就可以避免被回收:如下:

for (var i = 0; i < lg; i++) {//lg = 6
            setTimeout((function(a) {
                console.log(a);//操纵变量a,和i无关 此时输出为0,1,2,3,4,5
            })(i), 1000);//将 i 作为变量传入
}

但是这样写会出现一个问题,函数直接打印了,并没有一秒的延迟,原因是将自执行函数放在定时器中,会直接执行,并不是1秒后再执行,所以在这种方法上做了一些改进,即第二种方法:

第二种方法:将延时器整个的包裹在一个子执行函数中,这样就相当于同时定义了6个延时1s的延时器:

for (var i = 0; i < lg; i++) {//lg = 6
        (function(a){//自执行函数,获取i
            setTimeout(function() {
                console.log(a);//操纵变量a,和i无关 此时输出为 0,1,2,3,4,5 且在1s延迟后输出
            }, 1000)
        })(i)
    }

这样就完美的解决问题了;如果你想要每隔一秒输出一个值,而不是同时输出,则可以将参数传进时间中:

 for (var i = 0; i < lg; i++) {//lg = 6
        (function(a){//自执行函数,获取i
            setTimeout(function() {
                console.log(a);//操纵变量a,和i无关 此时输出为 0,1,2,3,4,5 且在1s延迟后输出
            }, a*1000)//将 i 的值传进来 ,这样就可以每个一秒输出一个值
        })(i)
    }

setInterval定时器和setTimeout 不同,因为是执行次数的原因,不能将 i  的值传进时间中,会造成多次重复;

时间: 2024-08-24 19:39:44

for循环 嵌套延时器 实例及解决方案的相关文章

4循环嵌套和方法

1 循环嵌套 循环嵌套(多重循环):一个循环结构中的循环体包含其他的循环结构. 任意两种循环结构都可以相互嵌套. for(表达式1;表达式2;表达式3){ for(表达式1;表达式2;表达式3){ } } 特点:外层循环执行1次,内层循环有可能执行多次. 只有当内层循环执行结束后,才会执行下次的外层循环. 示例1:打印3行8列的矩形矩形 public class TestLoop{ public static void main(String[] args){ //外层循环控制行数 for(in

延时器setTimeout()和定时器setInterval()

延时器setTimeout() var timer = window.setTimeout(code,millSec); 返回值是一个延时器,timer只是一个数值ID,可以用clearTimeout() 方法来终止,若含有多个setTimeout,可以通过这个数值ID来确定结束哪一个 setTimeout() 方法. setTimeout()方法只执行一次,不会重复执行,想要实现重复执行,可以通过递归函数的调用. 定时器setInterval() var timer = window.setI

Flex4/Flash+BlazeDS+JAVA+MySql 开发在线音乐播放器实例

要求 必备知识 本文要求基本了解 Adobe Flex编程知识和JAVA基础知识. 开发环境 MyEclipse10/Flash Builder4.6/Flash Player11及以上 演示地址 演示地址 传统网络程序的开发是基于页面的.服务器端数据传递的模式,把网络程序的表现层建立于HTML页面之上,而HTML是适合于文本的,传统的基于页面的系统已经渐渐不能满足网络浏览者的更高的.全方位的体验要求了.而富互联网应用(Rich Internet Applications,缩写为RIA)的出现就

SQL连接操作符介绍(循环嵌套, 哈希匹配和合并连接)

今天我将介绍在SQLServer 中的三种连接操作符类型,分别是:循环嵌套.哈希匹配和合并连接.主要对这三种连接的不同.复杂度用范例的形式一一介绍. 本文中使用了示例数据库AdventureWorks ,下面是下载地址:http://msftdbprodsamples.codeplex.com/releases/view/4004 简介:什么是连接操作符 连接操作符是一种算法类型,它是SQLServer优化器为了实现两个数据集合之间的逻辑连接选择的操作符.优化器可以基于请求查询.可用索引.统计信

Python 循环嵌套

Python 循环嵌套 Python 语言允许在一个循环体里面嵌入另一个循环. Python for 循环嵌套语法: for iterating_var in sequence: for iterating_var in sequence: statements(s) statements(s) Python while 循环嵌套语法: while expression: while expression: statement(s) statement(s) 你可以在循环体内嵌入其他的循环体,如

JS中的循环结构、循环嵌套以及函数介绍

[循环结构的步骤]    *①声明循环变量    *②判断循环条件    *③执行循环体(while的{}中的所有代码)操作     *④更新循环变量    *     * 然后,循环执行②③④    *     *     * [JS中循环条件支持的数据类型]    * ①boolean:true 真     false   假    * ②string: 非空字符串为真       空字符串为假    * ③null/NaN/undefined:  全为假    * ④object:全为真 

for循环嵌套

七.for循环嵌套 (一)格式 for(初始条件;循环条件;循环调整) { for(初始条件;循环条件;循环调整) { 循环体 } } (二)例题 1.一个游戏,前20关每一关是自身的分数,21~30关每一关是10分,31~40关每一关是20分,41~49关每一关是30分,第50关是100分,输入你现在闯到的关卡数,求你现在拥有的分数. 主要代码: (1)法一 while (true) { Console.Write("请输入你闯到的关卡:"); int c = int.Parse(C

使用JavaScript循环嵌套解决各种图形

[循环嵌套的规律]    1.外层循环控制行数,内层循环控制每行中元素的个数. [图形题思路]    1.确定图形有几行,行数即为外层循环次数:    2.确定每行中有几种元素组成,有几种元素表示有几个内层循环:    3.确定每种元素的个数,这个个数即为每个内层元素循环次数.     如果每种元素的个数不固定,则找出每种元素的个数,与行号的关系,     这个关系表达式即为内循环的最大值. 1.长方形 1 <!DOCTYPE html> 2 <html> 3 <head&g

for循环和循环嵌套

通过一周对c#的学习,发现很多同学在循环这一块都有点晕,其实只要一步一步的去分析执行步骤和条件,思路清晰了,自然就理解了; 而且很多时候都会for循环里面再嵌套for循环,这样如果思路不清晰,那当然就会一脸懵逼; 下面我来用几个例子,来浅谈下for循环和循环嵌套,希望对大家有所帮助; ①.输出五行五列; 我们来分析下循环过程: 1.当i=0的时候,执行内层循环 j=0,输出一个*号,然后j++;这时候j=1,输出第二个*号,然后j++;......;j=4的时候输出第五个*号,然后j++;这时候