为什么JavaScript是单线程?
- JavaScript作为一门浏览器脚本语言,其主要作用就是用户交互以及操作DOM,如果js是多线程,那么岂不是用户在交互的时候,我们也可以在另一个线程中把交互的DOM节点给删除,这样就会乱套了,因此,js只能是单线程
事件循环
- JavaScript通过任务队列来控制异步任务的执行
- 首先所有同步任务都在主线程上执行,形成一个执行栈,当主线程上的任务都执行完成了之后,看一下任务队列中有没有任务,有则从任务队列中取出首部的任务,压入执行栈,执行任务,执行完了之后继续看任务队列中有没有任务,重复原来的步骤,没有的话则继续检查任务队列中有没有任务(这里有点像轮询的方式,因为可能后面突然加了个异步任务进来)
宏任务和微任务
- 为了更好的管理异步任务,js设立了宏任务队列和微任务队列,因此,我们可以将上面的任务队列拆分成宏任务队列和微任务队列
- 宏任务有:
ajax
,setTimeout
,setInterval
,DOM监听
等,微任务有:Promise的then或者catch的回调
,Mutation Observer API
,queueMicrotask()
,process.nextTick
等 - 接到上面的事件循环,每一次从任务队列中取任务的时候,会先看一下微任务队列里面的任务,如果微任务队列中有任务,则取出队首的任务放入执行栈,执行任务,倘若微任务队列中没任务了,则再看宏任务队列里面的任务,有任务则取出队首的任务放入执行栈,执行任务
- 从上面可以看出,微任务队列的优先级更高,每次执行宏任务都要保证微任务队列中没有任务