5.事件循环篇
event Loop 即事件循环,是浏览器或
Node
解决单线程运行时不会阻塞的一种机制。
1.单线程却可以异步
JavaScript
的确是一门单线程语言,但是浏览器UI
是多线程的,异步任务借助浏览器的线程和JavaScript
的执行机制实现。 例如,setTimeout
就借助浏览器定时器触发线程的计时功能来实现。
2.浏览器线程GUI
渲染线程
1.
JS
引擎线程2.事件触发线程
- 当对应的事件满足触发条件,将事件添加到js的任务队列末尾
- 多个事件加入任务队列需要排队等待
3.定时器触发线程
- 负责执行异步的定时器类事件:setTimeout、setInterval等
- 浏览器定时计时由该线程完成,计时完毕后将事件添加至任务队列队尾
4.
HTTP
请求线程
- 负责异步请求
- 当监听到异步请求状态变更时,如果存在回调函数,该线程会将回调函数加入到任务队列队尾
3. 同步与异步执行顺序
JavaScript
将任务分为同步任务和异步任务,同步任务进入主线中中,异步任务首先到Event Table
进行回调函数注册。- 当异步任务的触发条件满足,将回调函数从
Event Table
压入Event Queue
中。 - 主线程里面的同步任务执行完毕,系统会去
Event Queue
中读取异步的回调函数。 - 只要主线程空了,就会去
Event Queue
读取回调函数,这个过程被称为Event Loop
。
举个例子:
- setTimeout(cb, 1000),当1000ms后,就将cb压入Event Queue。
- ajax(请求条件, cb ),当 http 请求发送成功后,cb压入Event Queue。
常见的异步任务
DOM
事件AJAX
请求- 定时器
setTimeout
和setlnterval
ES6
的Promise
4. 宏任务与微任务
异步任务还分为宏任务和微任务
1.执行顺序(先微任务在宏任务 promise是微任务)
1.代码开始执行,创建一个全局调用栈,script
作为宏任务执行
2.执行过程过同步任务立即执行,异步任务根据异步任务类型分别注册到微任务队列和宏任务队列
3.同步任务执行完毕,查看微任务队列
- 若存在微任务,将微任务队列全部执行(包括执行微任务过程中产生的新微任务)
- 若无微任务,查看宏任务队列,执行第一个宏任务,宏任务执行完毕,查看微任务队列,重复上述操作,直至宏任务队列为空