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.

原文地址:https://www.cnblogs.com/xiaoxu-xmy/p/13663498.html