• JS 同步与异步编程


    JS同步与异步编程

    JS是单线程的, js就是个傻子, 脑子一根筋, 做着当前的这件事情, 没有完成之前绝不会做下一件事情

    JS中的两种编程思想

    同步

    上一件事情没有完成, 继续处理上一件事情, 只有上一件事情完成了, 才会做另一件事情(JS中大部分都是同步编程的)

    for(var i = 0; i < 10000; i ++){
        if  i == 9999(){
            console.log("循环结束了~~")
        }
        console.log("ok")
    }
    

    -> 循环结束了~~
    -> ok

    for循环就是同步编程的, 只有循环结束后, 才会继续执行下面的代码

    while(1){
    
    }
    console.log("ok")
    

    永远都不会执行 console.log("ok"), 因为上面的循环是死循环, 永远都不会结束

    异步

    规划要做一件事情, 但是不是当前立马去执行这件事情, 需要等一定的时间, 这样的话, 我们不会等着它执行, 而是继续执行下面的操作, "只有当下面的事情都处理完成了", 只有当下面的事情都处理了, 才会返回头处理之前的事情; 如果下面的事情并没有处理完成, 不管之前的事情有没有到时间, 都踏踏实实的给我等着

    实现方法

    在JS中异步编程只有四种情况:

    • 定时器都是异步编程的
    • 所有的事件都是异步编程的
    • Ajax读取数据的时候, 我们一般都设置为异步编程
    • 回调函数也都是异步编程的

    定时器

    var n = 0;
    window.setTimeout(function(){
        n++;
        console.log(n);
    }, 1000);
    console.log(n);
    

    -> 0
    -> 1

    不立即执行

    每一个浏览器对于定时器的等待时间都有一个最小的值, 谷歌:5~6ms IE:10~13ms, 如果设置的等待时间小于这个值, 不起作用, 还是需要等到最小时间才执行; 尤其是写0也不是立即执行.

    var n = 0;
    window.setTimeout(function(){
        n++;
        console.log(n);
    }, 0);
    console.log(n);
    

    -> 0
    -> 1

    不保证准确的执行时间

    我们定时器设置的等待时间不一定就是最终执行的时间, 如果定时器之后还有其他的事情正在处理中, 不管定时器的时间有没有到, 都是不会执行定时器的

    var n = 0;
    window.setTimeout(function(){
        n++;
        console.log(n);
    }, 0);
    console.log(n);
    while(1){
        n++
    }
    console.log(n)
    

    -> 0
    进入死循环, 浏览器卡死

    任务队列
    var n = 0;
    window.setTimeout(function (){
        n += 2;
        console.log(n)
    }, 2);
    
    window.setTimeout(function (){
        n += 5;
        console.log(n)
    }, 1);
    
    console.log(n);
    for(var i =0; i < 10000000; i++){
        
    }
    console.log(n);
    

    -> 0
    -> 0
    -> 5
    -> 7

    任务队列

    任务队列池

    任务 -> 2ms执行

    将任务->1ms执行添加到队列池中, 发现时间更短的在任务队列中提前排列

    任务 -> 1ms执行
    任务 -> 2ms执行

    执行区

    var n = 0;
    console.log(n); ->0
    执行一千万次的循环, 可能消耗的时间大于20ms也可能小于20ms
    console.log(n) -> 0
    此时的立即执行的任务都完成了

    返回头
    开始按照任务池中的任务队列的顺序开始从上到下执行.

    事件

    for(var i=0; i<oLis.length;i++){
        oLis[i].onclick = function(){
            console.log(i);
        }
    }
    

    -> 3
    -> 3
    -> 3

    用户点击的时候, 循环已经执行完了, i已经变成了3.

  • 相关阅读:
    Log4php使用指南
    【JQuery】使用JQuery 合并两个 json 对象
    【前端】JS截取字符串常用方法详细整理
    【.Net】net 反射15分钟速成
    【.Net】win10 uwp unix timestamp 时间戳 转 DateTime
    【ASP.NET Core】ASP.NET Core 依赖注入
    【ASP.NET 框架系列】您所经历的,但未必研究的那些技术
    Visual Studio 中设置npm
    【数据库】SQL分组多列统计(GROUP BY后按条件分列统计)
    【数据库】同一字段根据不同条件更新的sql语句的写法
  • 原文地址:https://www.cnblogs.com/xiaoxu-xmy/p/13663498.html
Copyright © 2020-2023  润新知