一 什么是JavaScript?
js是单线程,异步,非阻塞的解释型脚本语言
二 为什么JavaScript是单线程?
如果JavaScript不是单线程,那意味着可以同时执行多个任务,假如不是单线程,同时有两个任务都对dom进行了操作,一个添加节点,一个删除节点,浏览器会去执行哪一个线程呢?
在html5中推出了web worker 标准,允许JavaScript创建多个线程,但是子线程完全受主线程控制且不得操作dom,所以也是没有违背js单线程的本质
三 异步非阻塞
这里说javascript 是单线程指的是负责解释和执行js代码的只有js引擎线程,但是浏览器的渲染进程是多线程的,里面就包括(js引擎线程,定时器线程,http请求线程,gui渲染进程,事件触发进程)
js引擎在处理任务的时候,遇到定时器,网络请求,dom事件监听会直接将它们交付给webapi,也就是浏览器提供的相对应的线程,js引擎继续执行后续的任务,这样就实现了 异步非阻塞
那么什么时候来执行呢?以定时器为例,当设定的事件一到,定时器就会将它里面的回调函数交由消息队列去维护,js引擎会在合适的时候去取出消息并执行
js引擎什么时候去处理呢?消息队列又是什么?
三 事件循环与消息队列
事件循环机制和消息队列机制是由事件触发线程控制的
事件触发线程同样是由浏览器渲染引擎提供的,当异步事件到了特定的时候(定时器结束,网络请求成功,用户点击dom),然后由事件触发线程将异步对应的回调加入到消息队列中,消息队列中的函数等待被执行.
同时,js引擎会维护一个执行栈,同步代码将会依次加入执行栈然后执行,结束后退出执行栈
当执行栈中的任务执行完成(js引擎空闲),事件触发线程就会将消息队列中的一个任务(异步里面的回调)加入到
执行栈中执行,当这个事件执行完后,执行栈再次为空,执行上一步操作,再次从消息队列取出任务放入执行栈,循环此操作,这种机制就叫做事件循环机制.
四 宏观任务与微观任务
以上的机制在es5中是够用了,但在es6中增加了Promise,async 等
每次执行栈中的代码就是一个宏任务,包括宏任务队列里面的,执行栈中的任务执行完毕后会去宏任务队列取任务加入执行栈,同样是事件循环
在执行宏观任务遇到promise,会创建微观任务(then里面的回调),并加入微观任务队列队尾
微观任务必然是某个宏观任务执行的时候创建的,在将宏观任务队列中的一个任务加入到执行栈中之前,会先
将微观任务队列中的任务执行完
over