JavaScript异步和单线程

1、异步:

不会卡顿在异步代码那里直接向下执行代码,等待同步代码执行完成后自动触发异步代码的执行。 (比如ajax、定时器)

console.log(100);
setTimeout(function(){
	console.log(200);
},1000);
console.log(300);

输出结果解析:立刻打印出100,然后300,等待一秒后打印200

2、同步:

代码按顺序执行,执行的流程不能跨越,需要等待结果完成后才能继续向下执行代码。(比如信息提示弹框,登录和删除功能)

console.log(100);
alert(200); //一秒后再点击确定
console.log(300);

输出结果解析:立刻打印出100,然后弹出提示框,一秒后点击确定按钮后再打印300

3、前端开启异步任务的场景
  • 定时任务:setTimeout(),setInterval()
  • 网络请求:ajax请求,动态< img />加载
  • 事件绑定:onclick等事件
4、js单线程

js是单线程的,同一个时间只能做一件事,所有任务需要排队,前一个任务结束,才会执行后一个任务。
在执行有同步代码和异步代码的代码块中,会优先把所有的同步代码都执行完,才会去执行异步代码,在同步代码执行完之前,是不会去响应异步代码的。

1. 同步任务和异步任务的优先级

	console.log(111);
    setTimeout(function(){
        console.log(222)
    },0);
    while(1){
        
    }

运行结果分析: 只直接打印出 111 ,然后代码进入死循环,一直没有执行完同步的循环,所以不会执行异步代码。

2. 异步任务的放入和执行时间

for(var i = 0; i < 4; i++){
    setTimeout(function(){
        console.log(i)
    },1000)
}
//上面的代码改写为下面这种形式更好理解一些
for(var i = 0; i < 4; i++){
fn();
}
function fn(){
	setTimeout(function(){
        console.log(i)
    },1000)
}

运行结果分析:一秒之后输出4个4。
当同步代码for循环体循环完了这时全局变量 i 已经是 4了。
在循环的时候每次碰到异步setTimeout任务,浏览器的timer模块先把异步代码提出来,等到1s后浏览器的timer模块才会把定时器的函数体扔到异步队列中,然后异步队列再等待事件循环(event loop)来执行。执行了那四个函数function(){ console.log(i) },所以就打印出了4个4。

5、异步和单线程
众所周知,js是单线程的,但是我们又经常说js异步,这是为什么呢?为什js是单线程的呢?

JavaScript的单线程,与它的用途有关。作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准?

实际上浏览器的渲染过程是多线程的,它不只有js一个线程,它还有GUI渲染线程、事件触发线程、定时触发器线程、异步http请求线程等线程。
js一次只能执行一个任务,当他有许多任务时,由于单线程,所以这些任务只能形成一个任务队列排队一个一个来,当前端的某些任务是非常耗时的,比如网络请求,定时器和事件监听,如果让他们和别的任务一样,都老老实实的排队等待执行的话,执行效率会非常的低,甚至导致页面的假死。所以,浏览器为这些耗时任务开辟了另外的线程,主要包括http请求线程,浏览器定时触发器,浏览器事件触发线程,这些任务是异步的。
所以说js单线程和异步并没有什么关系。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值