zoukankan      html  css  js  c++  java
  • 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功能,可以写多线程

  • 相关阅读:
    centos 安装 TortoiseSVN svn 客户端
    linux 定时任务 日志记录
    centos6.5 安装PHP7.0支持nginx
    linux root 用户 定时任务添加
    composer 一些使用说明
    laravel cookie写入
    laravel composer 安装指定版本以及基本的配置
    mysql 删除重复记录语句
    linux php redis 扩展安装
    linux php 安装 memcache 扩展
  • 原文地址:https://www.cnblogs.com/charleswone/p/10228699.html
Copyright © 2011-2022 走看看