js是单线程和异步

延迟0秒有啥用?这里就衍生出JS的代码执行流程的问题
大家都知道javascript是单线程,正常情况下javascript都是按照顺序执行的。但是我们可以让某段代码后面的代码先执行,这时就可以用到setTimeout延时0ms来实现了。如:

console.log(1)
setTimeout(function(){console.log(2); }, 0); 
console.log(3)

执行的结果依次:1 3 2
之所以会出现这样结果是因为setTimeout(fn, 0)将console.log(2);语句添加到了执行队列的队尾,即便只是延迟0ms也需要等栈中的同步任务都执行完毕后,再执行。因为栈中的同步任务也会耗时,所以间隔的时间一般会大于等于指定的时间,不会立即执行!

拓展知识

单线程与异步: js是单线程和异步,听到这句话是不是感觉很奇怪这两两者本身是相互矛盾的,理论上是不能同时存在的,因为是单线程,程序的执行顺序就是从上到下依次执行,同一时间内只能有一段代码被执行。

那么问题来了:当浏览器请求了一个返回非常慢的接口,那么页面就无法继续运行下去,页面卡住这就形成了“阻塞程序”,这显然是不对的。而且我们的浏览器本身就存在大量的异步请求,如果都需要一个个等待那么浏览器就无法正常运行了,这就注定js即使是单线程,也必须支持异步。那怎么办?

最终解决方式: 虽然JavaScript是单线程的,可是浏览器内部不是单线程的。那么js只执行自己程序的代码,当遇到异步操作时丢给浏览器,由浏览器的线程去执行丢入队列中,自己继续往下执行就能解决这个问题了。
在这里插入图片描述

  • WebAPIs:浏览器为异步任务单独开辟的线程(服务JavaScript的,处理JavaScript的异步)
  • 虚线部分:堆(heap)和栈(stack)共同组成了js主线程(这个就是我们JavaScript的线程)
  • callback queue:任务队列,里面放着各种事件,比如我们点击所触发的事件,浏览器会帮我们以任务的形式,把他放入任务队列中
  • event loop:任务循环,又叫事件循环。当所有主线程执行完毕后,所有的函数就都被推出了栈,而这个时候就会通过event loop(事件循环)去任务队列中将先前的异步操作推入栈中执行(就是我们异步的回调函数),但这个时候就不是异步操作了而是同步了。

总结

通过扩展知识的补充,想必大家都已经理解setTimeout(fun,0)的执行流程了。总的来说javascript一直都是单线程的,并没有去实现异步,而真正的异步操作是浏览器完成的。浏览器把异步操作通过回调行数的形式把任务丢到了队列中,当js的主线程都执行完毕,之后又会再去队列中将回调函数推入栈(stack)中继续执行。

1.js是单线程和异步原理视频
2.node的Event loop和javaScript 的Event loop 不同点
以上就是我对setTimeout和javascript单线程和异步机制的一些理解,如果文章由于我学识浅薄,导致您发现有严重谬误的地方,请一定在评论中指出,我会在第一时间修正我的文章,以避免误人子弟。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值