进程和线程
一个浏览器只有一个主进程,负责管理Tabs,协调其他process和Renderer Process
简单来说:打开一个页面是一个进程,一个进程卡死不会影响到另一个进程
其中Renderer process是multi-thread,其中main thread负责渲染(GUI render engine)执行JS(JS engine)和event loop
- 进程是操作系统的最小单位
- 一个进程会占用一个端口,
- 一个进程可以包含多个线程 ,通过多个线程去完成并发
JS执行上下文
对象与每个执行上下文,都有三个重要的属性:
- 变量对象(variable object)
- 作用域链(scope chain)
- this
处理上下文代码的几个阶段
- 确定变量对象
- 确定作用域链
进入执行上下文
一旦进入执行上下文(再执行代码之前)。VO就会被一些属性填充:
- 函数的形参
- 变量对象的我一个属性,其属性名就是形参的名字,其值就是实参的值,对于没有传递的参数,器值为undefined
- 函数声明
- 变量对象的一个属性,其属性名和值都是函数对象创建出来的;如果变量对象已经包含了相同的名字属性,则替换它的值
- 变量声明
- 变量对象的一个属性,其属性名即为变量名,其值为undefined;如果变量名和已经声明的函数名或者函数的参数名相同,则不会影响已经存在的值
Code
1 | alert(x); |
执行对象
浏览器的Event Loop
一个函数执行栈,一个事件队列和一个微任务队列
每从事件队列中取一个事件时有微任务就把微任务执行完,然后才开始执行事件
宏任务与微任务
- 宏任务,macrotask, 也叫tasks.一些异步任务的回调会依次进入macro task queue,等待后续被调用,这些异步任务包括
- setTimeout
- setInterval
- setImmediate(Node独有)
- requestAnimationFrame(浏览器独有)
- I/O
- UI rendering(浏览器独有)
注意:同步代码会当成宏任务处理
- 微任务,microtask,也叫jobs。另一些异步任务的回调会依次进入micro task queue,等待后续被调用,这些异步包括:
- process.nextTick(Node独有)
- Promise.then()
- Object.observe
- MutationObserver
注意:Promise构造函数里的代码是同步执行的
Code
1 |
|
为什么上面的代码中会有promise对象
- 因为代表的是第一轮的事件循环的结束
堆栈的溢出
当执行一段死循环的代码时,任务就会一直放到堆栈里,一直放会导致堆栈的溢出,解决这个办法可以用异步的操作来解决