1 进程与线程
进程描述了CPU在运行指令及加载和保存上下文所需的时间,放在应用上来说就代表了一个程序。线程是进程中的更小单位,描述了执行一段指令所需的时间。
在浏览器环境中,打开一个tab就是创建一个进程,一个进程中可以有多个线程,比如渲染引擎、JS引擎线程、HTTP请求线程等等。当发起一个请求时,其实就是创建了一个线程,当请求结束后,该线程可能就会被销毁。
当JS运行的时候可能会阻止UI渲染,这说明了两个线程是互斥的。这其中的原因是因为JS可以修改DOM,如果在JS执行的时候UI线程还在工作,就可能导致不能安全的渲染UI。
1 浏览器中的Event Loop
当我们执行JS代码时其实就是往执行栈中放入函数,遇到异步函数会被挂起并在需要执行的时候加入到Task队列中。一旦执行栈为空,Event Loop就会在Task队列中拿出需要执行的代码并放入到执行栈中执行。
不同的任务源会被分配到不同的Task队列中,任务源可以分为微任务和宏任务。在ES6规范中,microtask成为jobs, macrotask成为task。
console.log('script start')
async function async1() {
await async2()
console.log('async1 end')
}
async function async2() {
console.log('async2 end')
}
async1()
setTimeout(function() {
console.log('setTimeout')
}, 0)
new Promise(resolve => {
console.log('Promise')
resolve()
})
.then(function() {
console.log('promise1')
})
.then(function() {
console.log('promise2')
})
console.log('script end')
// script start =>
// async2 end =>
// Promise =>
// script end =>
// async1 end =>
// promise1 =>
// promise2 =>
// setTimeout
从以上输出结果,事件执行顺序如下:
往期相关文章:https://mp.weixin.qq.com/s/2SXuoPdyQWA_fxQiIx8Wfg
可以一起看看~
温故知新~