1.js是单线程?
为什么是单线程,首先就要理解什么是单线程,单顾名思义就是同一时间完成同一件事,其实生活中也很多这样的例子,比如你做菜,肯定是提前把 材米油盐以及配菜准备好,才可以进行下面炒菜的环节,也就是在保证顺序的情况下,在某个特定的时间内专心做件事,备菜时间就备菜,切菜时间就切菜,这就是我们生活中的一个例子
2.那么js为什么是单线程的?
其实js作为脚本语言,跟他的用途相关的,因为js面向的是浏览器,是不停的在我们DOM树上进行节点的操作,如果js开启了两个线程,第一个线程是在DOM树上添加节点,宁外一个线程是在DOM上删除节点,那么浏览器应该以哪个线程为基准呢,所以,这很容易引起复杂的同步问题!
3.浏览器是怎么将我们代码进行渲染的?
1.首先,浏览器,通过我们写的 HTML 标签,把我们的 HTML 标签解析为一个DOM树,DOM树的每一个节点对应每一个Html(节点元素),每一个文本对应每一个 文本(文本元素)
2.在DOM解析完毕后,浏览器会把 我们写的 css 样式文件进行一个过滤,把非法css语法进行过滤,得到最终的样式文件,
3.在得到 DOM 树与 样式文件之后,浏览器 js 引擎会根据得到的资源在浏览器页面上绘制网页
4.process.nextTick(callback)
在同步代码执行完毕后运行,也就是 执行栈 中代码运行完后执行
5.setImmediate(()=>{},detaly)
在异步代码执行完成后运行,也就是 **当前 **任务队列里执行完毕后执行(注意:是当前任务队列执行完毕后执行)
console.log(1111);
// 同步代码执行后 执行
process.nextTick(() => {
console.log(3333);
})
console.log(2222);
// 异步
setTimeout(() => {
console.log(4444);
}, 500);
// 当前事件循环结束才执行
setImmediate(() => {
console.log(5555);
})
// 输出结果 111 222 333 5555 4444
不是 异步代码执行完毕后 才执行 setImmediate 吗?这里的 5555 为什么在 4444 的前面,关键还在于 setImmediate 的特点,他在 当前 事件循环结束后才执行,而定时器有 500 的延迟,在当前事件循环后的下次事件循环才执行
6.事件循环
谈及事件循环,就要涉及 执行栈,任务队列
执行栈
在 js 中只要是 同步代码,存放在 执行栈中
任务队列
在 js 中只要是 异步代码,存放在 任务队列中
那么事件循环跟任务队列,执行栈什么关系呢?在我们js执行的过程中,肯定会有同步,异步代码,这个时候,js会把同步代码放在我们的js执行栈中,异步代码放在我们的任务队列里面,在同步代码执行完毕后,我们的事件循环会对任务队列里面的异步代码进行不断的监测,然后按照顺序一一致性