Bootstrap

解决for循环中的异步问题以及var let const的区别

一、var let const的区别

var 没有块级作用域、有变量提升,能重复声明。
let 有块级作用域、没有变量提升,不可重复声明。
const 有块级作用域、赋值常量后不可修改、没有变量提升、不可重复声明

参考图:
在这里插入图片描述
图片描述:
var 声明的循环:就是运行五次的setimeout代码 会放到右边异步队列,但不执行,里边的(i)等到左边同步的执行完才会执行,因为左边同步的var会重复声明覆盖变量值,只有在最后一个执行完才会输出, 而let则会锁住变量,也就是有块级作用域也就是右边异步队列会直接输出0,1,2,3,4,5

二、for循环中的异步问题

**问题描述:**当我们使用for循环时,里面执行异步操作(比如延时器,接口请求等等),就会出现里面执行的永远是最后一次循环的结果,原因是因为for循环是同步的,当异步操作还没走完,for循环已经全部执行完成了,所以得到的永远是最后一次的结果。

解决方法如下:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <p>1</p>
    <p>2</p>
    <p>3</p>
    <p>4</p>
    <p>5</p>

    <script type="text/javascript">
        window.onload = function () {
            // 问题描述:当我们使用for循环时,里面执行异步操作(比如延时器,接口请求等等),就会出现里面执行的永远是最后一次循环的结果,原因是因为for循环是同步的,当异步操作还没走完,for循环已经全部执行完成了,所以得到的永远是最后一次的结果。
            var ps = document.getElementsByTagName("p");
              
            // 方法一 使用闭包

            for (var i = 0; i < ps.length; i++) {
                   
                (function (r) {
                    setTimeout(function () {
                        console.log(r)
                    })
                })(i)

            }

            // 方法二:使用let 或 const块级作用域,每个for循环的变量只对本次循环有效

            for (let i = 0; i < ps.length; i++) {      
                    setTimeout(function () {
                        console.log(i)
                    })
            }
        }  
    </script>
</body>

</html>
;