zoukankan      html  css  js  c++  java
  • for循环中执行setTimeout问题(任务队列的问题)

    for(var i=0;i<8;i++){
        setTimeout(function () {
             console.log(i)
         },0)
     }

    输出了8次8,这跟js的执行顺序和作用域链有关。

      规则: 

      同步优先、异步靠边、回调垫底。    

      用公式表达就是:同步 => 异步(定时器  or  异步请求) => 回调

    1、js同步执行与异步执行
    js的执行机制: js是单线程环境,从上到下、依次执行,即 同步执行;在这段代码中,for循环是同步代码,setTimeout是异步代码。
    js在执行代码的过程中,碰到同步代码会依次执行,碰到异步代码就会将其放入任务队列中进行等待,当同步代码执行完毕后再开始执行异步代码,即 异步执行。

    2、js作用域问题
    当同步代码执行完毕后,开始执行异步的setTimeout代码,执行setTimeout时需要从当前作用域内寻找一个变量 i ,此时for循环已执行完毕,当前 i=8,所以执行setTimeout时输出为8,任务队列中的剩余7个setTimeout也依次执行,输出为8。

    3、常用解决方法
    利用立即执行函数,当for循环执行时,就会立即执行setTimeout,从而使得到的每个副本i值都不一样,这样就可以得到想要的for循环的结果。如:

    for(var i=0;i<8;i++){
        (function (x) {
            setTimeout(function () {
                console.log(x)
            },0)
        })(i);
    }
    参考:
        https://blog.csdn.net/ld767416042/article/details/84030668
        https://www.cnblogs.com/wangwenhui/p/7657654.html
        https://blog.csdn.net/huakaiwuxing/article/details/78968642

     https://baijiahao.baidu.com/s?id=1621653715044760064&wfr=spider&for=pc

    https://blog.csdn.net/u010297791/article/details/71158212

    https://blog.csdn.net/jssy_csu/article/details/78627628

  • 相关阅读:
    SQL的各种连接(cross join、inner join、full join)的用法理解
    解决sonarQube 'Unknown': sonar.projectKey
    DOS批处理高级教程
    java自定义注解
    inode备忘
    sed备忘
    awk备忘
    Oracle 删除表中记录 如何释放表及表空间大小
    Oracle 11g 分区拆分与合并
    Maven的settings.xml文件结构之mirrors
  • 原文地址:https://www.cnblogs.com/zhangchs/p/10964685.html
Copyright © 2011-2022 走看看