前言
JS是一门单线程语言,单线程就意味着,所有的任务需要排队,前一个任务结束,才会执行下一个任务。这样所导致的问题是:如果JS执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的觉。为了解决这个问题,JS中出现了同步和异步。他们的本质区别是:一条流水线上各个流程的执行顺序不同。在讲JS任务执行机制前,先要了解一下什么是同步任务与异步任务。
同步任务:既主线程上的任务,按照顺序由上至下执行,当第一个任务执行结束后才会执行第二个任务。
异步任务:不进入主线程,而是进入任务队列,执行完毕后会产生一个回调函数。并通知主线程,当主线·程执行完毕后,就会调取最早通知自己的回调函数,使其进入主线程执行。
1. 事件循环Event Loop概念介绍
- 事件循环又称为事件队列
- 事件循环使指js代码所在运行环境编辑器的一种解析执行规则。事件循环不属于js代码本身的范畴。而是属于js编辑器的范畴。在js中讨论事件循环是没有意义的。换句话说,js代码可以理解为是一个人在公司中具体做的事情,而事件循环相当于是公司的一种规章制度。
2.宏任务与微任务介绍
- 微任务与宏任务就属于js代码的范畴
- js代码分两大类:同步代码、异步代码
- 异步代码:宏任务、微任务
3.事件循环机制
- 进入到script就是进入到了第一次事件循环
- 遇到同步代码立即执行
- 遇到宏任务把它放入宏任务队列中
- 遇到微任务把它放入微任务队列中
- 执行完所有同步代码
- 执行微任务代码,本次队列清空
- 寻找下一个宏任务,重复上面的执行顺序。
- 以此反复直到清空所有宏任务,这种不断重复的机制被称为事件循环。
补充说明
- promise本身是一个同步的代码(只是容器),只有它后面调用的then()方法里面的回调才是微任务
- script标签本身是一个
宏任务, 当页面出现多个script标签的时候,浏览器会把script标签作为宏任务来解析
总结
- 所有同步任务都在一个主线程上执行,形成一个执行栈
- 遇到异步任务, 进入异步处理模块并注册回调函数; 等到指定的事件完成(如ajax请求响应返回, setTimeout延迟到指定时间)时,异步处理模块会将这个回调函数移入异步任务队列。
- 当栈中的代码执行完毕,执行栈中的任务为空时,主线程会先检查微任务队列是否有任务,如果有,则取出第一个宏任务加入到执行栈中,之后再清空执行栈,检查微任务,以此循环,直到全部的任务都执行晚餐。