• JS实现停留几秒sleep,Js中for循环的阻塞机制,setTimeout延迟执行


    //第一种,使用while循环
    function sleep(delay) {
        var start = (new Date()).getTime();
        while((new Date()).getTime() - start < delay) {
            continue;
        }
    }
    //或者使用for循环
    function sleep(delay) {
        for(var t = Date.now(); Date.now() - t <= d;);
    }

    这种实现方式是利用一个伪死循环阻塞主线程。因为JS是单线程的。所以通过这种方式可以实现真正意义上的sleep()。

    Js阻塞机制,跟Js引擎的单线程处理方式有关,每个window一个JS线程。所谓单线程,在某个特定的时刻只有特定的代码能够被执行,并阻塞其它的代码。

          由于浏览器是事件驱动的(Event driven),因此浏览器中很多行为是异步(Asynchronized)的,很容易有事件被同时或者连续触发。当异步事件发生时,会创建事件并放入执 行队列中,等待当前代码执行完成之后再执行这些代码,如鼠标点击事件发生、定时器触发事件发生、XMLHttpRequest完成回调这些事件,都会被放 入执行队列中等待。

          关于Js的阻塞机制,可以看下面一段代码,一般,我们会认为,这段代码会log出来0,1,2

    for(var i = 0; i < 3; i++) {
        setTimeout(function() {
            console.log(i);
        }, (i + 1) * 1000);
    }

          而实际上,这段代码log出来的结果是 3,3,3。这是js新手很容易遇到的问题,具体原因就是因为for循环的阻塞机制。在上面的代码中,setTimeout这个定时器需要等待for循环 执行完成,而for循环执行完成了之后,i已经为3了,此时才开始执行setTimeout,因此console.log(i)会是3。

          至于为什么i会是3,请回顾一下for循环的执行顺序,当i为2的时候,满足循环条件,执行代码块,然后i++,此时i为3,不满足循环条件,不执行代码块,循环停止。

          对于for循环,记住,是在不满足条件的情况下停止循环,对于以上代码,可以看出,i=3的时候才不满足。

    怎么解决事件阻塞

          其实,阻塞作为js引擎的处理方式,我们最好不要想着解决“阻塞”,而是让我们想执行的代码,插入到“主线程”中。这么说比较不易理解,还是以上面的代码为例,直接上代码好了

    for(var i = 0; i < 3; i++) {
        (function(i) {
            setTimeout(function() {
                console.log(i);
            }, (i + 1) * 1000);
        })(i)
    }

          再上面的代码中,我们加了一个立即执行的匿名函数,并且将for循环的i作为实参传入进去。这样,setTimeout就会被立即执行,而不会等待(这里不太了解细节,就不多说了,大概猜测为新开了一个临时的线程,立即执行匿名函数,然后再立即切换回来)。

          本文主要在说明如何解决这一类问题,对于底层原理,还待继续挖掘。

          注意:html5支持Web worker功能,可以写多线程

  • 相关阅读:
    zombodb 数据类型映射
    Amundsen — Lyft’s data discovery & metadata engine
    The Twelve-Factor Container
    zombodb sql functions 说明
    zombodb 得分以及高光
    windows openssh 设置root 目录
    zombodb 聚合函数
    zombodb 索引管理
    zombodb 索引创建
    zombodb 低级api 操作
  • 原文地址:https://www.cnblogs.com/charleswone/p/10228699.html
Copyright © 2020-2023  润新知