首先我们需要明白JS是单线程的,这是为了降低程序复杂性,但同时为了多个事件能同时被处理,JS提供了异步的处理方式(其实JS本身是没有异步这一说法的,都是由执行环境所提供的)。
众所周知,在使用JS时,经常需要考虑程序中存在异步的情况,如果对异步考虑不周,很容易在开发中出现技术错误和业务错误。作为一名合格的JS使用者,了解异步的存在和运行机制十分重要且有必要。
什么是单线程?
就行马路的单向通行道一样,一排车只能一辆一辆的排队前行通过。
程序同一时间只做一件事! 场景如下:
-
同步:同步阻塞的概念指的是A调用B,B执行完获得结果返回给A,A在等待B执行过程中是停滞的状态,直到拿到结果才会往下执行。
-
异步:异步与同步一样,其实也是一种消息通知机制,引用上面的比方,A调用B,无需等待B的结果,A继续往下执行,的同时B也在执行,B通过状态、通知等方式来通知A或者走回调来处理结果,做一件事的时候不用等待事情的结果,继续往下走,等有了结果再来通知我。
event loop
- 字面意思是事件循环,也是JS运行环境中的椅子不会阻塞线程的机制,也就是实现异步的原理。
JS程序执行时,所有事件任务被分为两种:宏任务(MacroTask/Task)
和微任务(MircoTask)
; - event loop的职责就是将各任务分别管理,列分为
Task Queue
队列和MircoTak Queue
队列,分别对应管理宏任务和微任务;作为队列它们具备了队列特性:先进后出
说到微任务宏任务,我们首先应该明白什么是微/宏任务。
常见微任务:
Promise中的then、catch、finally
nextTick
MutationObserver
常见宏任务:
<script>script标签中的内容</script>
DOM 操作
用户交互操作
网络请求
定时器方法
JS程序自上而下被执行,执行到同步任务直接进入到主线程中,当执行到异步任务则进入event table,当异步任务有结果后将相对应的回调函数注册使用,放入event queue,当主线程任务执行完得闲的时候,就会从event queue中查询任务,放入主线程中执行,接下来继续重复整套流程。
常见面试题大概如下题型:
最后打印结果如下顺序:
常见题型解法2:
如下图 分割成两栏,从上往下执行,直接执行的函数划到当前宏任务的大框中,微任务在小框中,内部宏任务在下一栏的大框中
以上就是JS中异步的原理与执行过程,有什么疑问或者发现文章内容错误请及时提出,感谢阅读~