JS中for和setTimeout配合使用易错点分析

现在很多前端小伙伴太过注重各类框架的学习,各类第三方包的使用;但是冷落了好些开发最重要的前端基础。没有基础,怎能建成高楼大厦呢?会些基本的node、php、python后端语言,mysql、mongodb数据库,会用些后端框架,模板解析框架,写些api,文件系统操作等,然后动不动就把全栈挂在嘴巴上,这样做意义好像真心不大。学习是一个不断重复的过程,基础知识一个需要不断回顾的过程,一切的框架第三方库都是基于原生实现,多看源代码,努力学好原生,跑遍天下浏览器不卡壳;从今天起,坚持每隔一两天总结些比较有趣的原生JS的小练习,多多练习回顾下。

 

回顾练习for循环相关易错点:

 

1.for循环配合setTimeout

 

(1)解决下面的输出问题,想要得到的结果为:0 1 2 3 4 5

function a(i){
      console.log(i);  // 5 5 5 5 5
    }
    for (var i = 0; i < 5; i++) { 
      setTimeout(function(){
        a(i);
      },1000); 
}

解决办法:

    function a(i){
      setTimeout(function(){
           console.log(i)
      },1000); 
    }

    for (var i = 0; i < 5; i++) { 
          a(i);
    }

(2)for循环同时开启5个定时器 

  for (var i = 0; i < 5; i++) {
        setTimeout(function() {
            console.log(new Date, i);
        }, 2000);
    }

    console.log(new Date, i);

    //打印如下:
    /*
        demo.html:17 Thu Nov 15 2018 11:11:21 GMT+0800 (中国标准时间) 5
        demo.html:13 Thu Nov 15 2018 11:11:23 GMT+0800 (中国标准时间) 5
        demo.html:13 Thu Nov 15 2018 11:11:23 GMT+0800 (中国标准时间) 5
        demo.html:13 Thu Nov 15 2018 11:11:23 GMT+0800 (中国标准时间) 5
        demo.html:13 Thu Nov 15 2018 11:11:23 GMT+0800 (中国标准时间) 5
        demo.html:13 Thu Nov 15 2018 11:11:23 GMT+0800 (中国标准时间) 5
*/

 

(3)解决上面的问题,希望可以输出 5  ->  0 1 2 3 4 5


1-3-1. 闭包解决

for (var i = 0; i < 5; i++) {
        (function(j) {  
            setTimeout(function() {
                console.log(new Date, j);
            },1000);
        })(i);
    }

console.log(new Date, i);

    //打印如下:
    /*
        demo.html:19 Thu Nov 15 2018 11:22:00 GMT+0800 (中国标准时间) 5
        demo.html:14 Thu Nov 15 2018 11:22:01 GMT+0800 (中国标准时间) 0
        demo.html:14 Thu Nov 15 2018 11:22:01 GMT+0800 (中国标准时间) 1
        demo.html:14 Thu Nov 15 2018 11:22:01 GMT+0800 (中国标准时间) 2
        demo.html:14 Thu Nov 15 2018 11:22:01 GMT+0800 (中国标准时间) 3
        demo.html:14 Thu Nov 15 2018 11:22:01 GMT+0800 (中国标准时间) 4
*/

1-3-2. 使用let

let i = 0;
    for (; i < 5; i++) {
        setTimeout(function() {
            console.log(new Date, i);
        },1000);
    }

console.log(new Date, i);

2. 优化上面的代码需要异步输出: 0 1 2 3 4 5

 

(1)第一种方法

for (var i = 0; i < 5; i++) {
    ~function(i){
        setTimeout(function() {
            console.log(new Date, i);
        }, 1000);
    }(i)
}

setTimeout(function(){
    console.log(new Date, i);
},1000)

//打印如下:
/*
    demo.html:21 Thu Nov 15 2018 13:49:25 GMT+0800 (中国标准时间) 0
    demo.html:21 Thu Nov 15 2018 13:49:25 GMT+0800 (中国标准时间) 1
    demo.html:21 Thu Nov 15 2018 13:49:25 GMT+0800 (中国标准时间) 2
    demo.html:21 Thu Nov 15 2018 13:49:25 GMT+0800 (中国标准时间) 3
    demo.html:21 Thu Nov 15 2018 13:49:25 GMT+0800 (中国标准时间) 4
    demo.html:27 Thu Nov 15 2018 13:49:25 GMT+0800 (中国标准时间) 5
*/

(2)第二种需求每隔1s输出:0 1 2 3 4 5,使用es6中的Promise解决方案

const tasks = [];
for (var i = 0; i < 5; i++) {   
    tasks.push(new Promise((resolve,reject)=>{
        (function(i){
            setTimeout(() => {
                console.log(new Date, i);
                resolve();
            }, 1000*i)
        })(i)
    }))
}

Promise.all(tasks).then(() => {
    setTimeout(() => {
        console.log(new Date, i);
    }, 1000);
})


//打印如下:
/*
    Thu Nov 15 2018 14:03:16 GMT+0800 (中国标准时间) 0
    demo.html:23 Thu Nov 15 2018 14:03:17 GMT+0800 (中国标准时间) 1
    demo.html:23 Thu Nov 15 2018 14:03:18 GMT+0800 (中国标准时间) 2
    demo.html:23 Thu Nov 15 2018 14:03:19 GMT+0800 (中国标准时间) 3
    demo.html:23 Thu Nov 15 2018 14:03:20 GMT+0800 (中国标准时间) 4
    demo.html:34 Thu Nov 15 2018 14:03:21 GMT+0800 (中国标准时间) 5
*/


(3)使用ES7中的async和await处理上诉问题,每隔1s输出 0 1 2 3 4 5 

  function sleep(time) {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve()
            }, time);
        } )
    }    
    
    async function timeout() {
        
        for(var i = 0;i<5; i++){
            await sleep(1000);
            console.log(new Date,i);
        }
        await sleep(1000);
        console.log(new Date, i);

        return '结束';
    }

    timeout().then(res => {
        console.log(new Date,res);
    })

    // 打印结果如下:
    /*

        demo.html:24 Thu Nov 15 2018 14:30:12 GMT+0800 (中国标准时间) 0
        demo.html:24 Thu Nov 15 2018 14:30:13 GMT+0800 (中国标准时间) 1
        demo.html:24 Thu Nov 15 2018 14:30:14 GMT+0800 (中国标准时间) 2
        demo.html:24 Thu Nov 15 2018 14:30:15 GMT+0800 (中国标准时间) 3
        demo.html:24 Thu Nov 15 2018 14:30:16 GMT+0800 (中国标准时间) 4
        demo.html:27 Thu Nov 15 2018 14:30:17 GMT+0800 (中国标准时间) 5
        demo.html:33 Thu Nov 15 2018 14:30:17 GMT+0800 (中国标准时间) "结束"

    */

 

你可能感兴趣的:(javascript,js,setTimeout,for)