for循环,定时器,闭包混合一块的那点事。

1,对于一个基本的for循环,顺序输出变量值。

        for(var i = 1; i < 4; i++){
            console.log(i);//结果不多说了吧
        }

2,如果for循环中有定时器,如下代码。

        for (var i = 1; i < 4; i++) {
            setTimeout(function() {
                console.log(i);//3个4
            }, 3000);
        }

初衷想要3s后输出1,2,3。但是3s后,输出3个4。原因是定时器的异步执行,for循环的执行速度很快,当真正执行到函数体时,此时i早已变成4,所以结果不想而知。

3,如果要得到正确结果,就要引入闭包来保存变量i不被销毁。

        for (var i = 1; i < 4; i++) {
            (function(a) {
                setTimeout(function() {
                    console.log(a);//操纵变量a,和i无关
                }, 3000);
            })(i)
        }

这样引入闭包,变量i保存下来,3s后函数体执行,输出1,2,3.

也可以这样写

         for (var i = 1; i < 4; i++) {
             setTimeout(fn(i), 3000);
         }
         function fn(a){
             return function(){
                 console.log(a);
             }
         }

4,如果要实现,没隔3s输出一个数字,即,3s输出1,3s后再输出2...,就要对定时器时间设置

        for (var i = 1; i < 4; i++) {
            (function(a) {
                setTimeout(function() {
                    console.log(a);
                }, a*3000); //.....
            })(i)
        }

实际上,for循环很快,上述代码类似于同时启动3个定时器,只需要确保时间不一样即可。在此,时间分别是3s,6s,9s,由于同时启动,但是执行时间不同,各个时间间隔都是3s。巧妙地达到了目的。

后续如果有补充,会继续添加...

时间: 2024-10-05 06:05:25

for循环,定时器,闭包混合一块的那点事。的相关文章

js settimeout定时 for循环问题 闭包

js settimeout定时 for循环问题 闭包先做个笔记 留待研究 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script type="text/javascript" src="jquery.1.7.2.min.js&q

深入理解闭包系列第四篇——常见的一个循环和闭包的错误详解

前面的话 关于常见的一个循环和闭包的错误,很多资料对此都有文字解释,但还是难以理解.本文将以执行环境图示的方式来对此进行更直观的解释,以及对此类需求进行推衍,得到更合适的解决办法 犯错 function foo(){ var arr = []; for(var i = 0; i < 2; i++){ arr[i] = function(){ return i; } } return arr; } var bar = foo(); console.log(bar[0]());//2 以上代码的运行

NSTimer单循环和多循环定时器讲解

本文将通过一个简单例子介绍一下NSTimer单循环和多循环定时器的使用方法. 创建一个Xcode工程,页面比较简单: 左侧部分实现了单循环定时器的创建.暂停.开启和停止功能,而右侧部分是多循环定时器的实现. 1.单循环定时器 定义定时器: NSTimer *singleCycleTimer; // 单循环定时器 功能实现: /* 创建单循环定时器 响应页面里"单循环"按钮 */ - (IBAction)createSingleCycleTimer:(id)sender { // 注:创

创建一个有上限的循环定时器

[代码质量差][英语质量差]见笑了 今天为了实现一个“取延时差异的资源并会提示超时”的功能时有一个地方想分享出来 /** * 创建有上限时钟 * @param {int} upperlimit 上限次数 * @param {int} cycle 间隔时间 * @param {Function} callback 回调函数 * @param {Function} completeCallback 执行完毕后调用的函数 * @return {Object} 返回一个时钟对象 */ function

一个循环和闭包的例子

1 for (var i=1; i<=5; i++) { 2 setTimeout(function timer() { 3 console.log(i); 4 }, i*1000); 5 } 预期:分别输出数字 1-5,每秒一次,每次一个. 实际上,会每秒一次输出 5次6,. 知识点: JS引擎是单线程的,定时器的工作方式:按指定时间间隔,将定时器的代码添加到JS引擎的消息队列:而非到了指定的时间立即执行回调函数. 在上例中, 作用域 尽管循环中的五个函数在各个迭代中分别定义,但都被封闭在一个

循环在闭包里的问题(写的不一定正确纯属阐述个人理解)

1 function box(){ 2 var arr=[]; 3 for(var i=0;i<5;i++){ 4 arr[i]=function(){ 5 return i; 6 } 7 } 8 return arr; 9 } 10 var cat=box(); 11 for(var i=0;i<5;i++){ 12 alert(cat[i]()); 13 } 看上面一段代码,总体看来alert(cat[i]());会分别输出0,1,2,3,4:其实不然,输出的全是5: 这时我们会产生疑问,

Swift语法基础入门三(函数, 闭包)

Swift语法基础入门三(函数, 闭包) 函数: 函数是用来完成特定任务的独立的代码块.你给一个函数起一个合适的名字,用来标识函数做什么,并且当函数需要执行的时候,这个名字会被用于“调用”函数 格式: func 函数名称(参数名:参数类型, 参数名:参数类型...) -> 函数返回值 { 函数实现部分 } 没有参数没有返回值 可以写为 ->Void 可以写为 ->() 可以省略 Void.它其实是一个空的元组(tuple),没有任何元素,可以写成() func say() -> V

浅析闭包和内存泄露的问题

JavaScript使用一种称为垃圾收集的技术来管理分配给它的内存.这与C这样的底层语言不同,C要求使用多少借多少,用完再释放回去.其他语言,比如 Objective-C,实现了一个引用计数系统来辅助完成这些工作,我们能够了解到有多少个程序块使用了一个特定的内存段,因而可以在不需要时清除这些内存段. JavaScript是一种高级语言,它一般是通过后台来维护这种计数系统. 当JavaScript代码生成一个新的内存驻留项时(比如一个对象或函数),系统就会为这个项留出一块内存空间.因为这个对象可能

JavaScript作用域闭包(你不知道的JavaScript)

JavaScript闭包,是JS开发工程师必须深入了解的知识.3月份自己曾撰写博客<JavaScript闭包>,博客中只是简单阐述了闭包的工作过程和列举了几个示例,并没有去刨根问底,将其弄明白! 现在随着对JavaScript更深入的了解,也刚读完<你不知道的JavaScript(上卷)>这本书,所以乘机整理下,从底层和原理上去刨一下. JavaScript并不具有动态作用域,它只有词法作用域.词法作用域是在写代码或者说定义时确定的,而动态作用域是在运行时确定的.了解闭包前,首先我