• 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.

  • 相关阅读:
    【SpringCloud构建微服务系列】分布式链路跟踪Spring Cloud Sleuth
    【算法】LRU算法
    细说分布式锁
    【Python】Python3.4+Matplotlib详细安装教程
    LoRaWAN协议(二)--LoRaWAN MAC数据包格式
    LoRaWAN移植笔记(一)__RTC闹钟链表的实现
    cJSON_json包的C语言解析库
    LoRaWAN协议(一)--架构解析
    STM32L051 PVD的调试
    以帧为存储单位的循环stack
  • 原文地址:https://www.cnblogs.com/xiaoxu-xmy/p/13663498.html
Copyright © 2020-2023  润新知