一、概念
1.进程:cpu正在进行的一个任务的运行过程的调度单位
*在浏览器中 每个table都会开启一个【进程】
*浏览器有一个主进程(用户界面)
*每个tab各自有独立的渲染进程
*每个进程包含了多个线程
2.线程
3.进程包含线程 线程在进程中运行
4.渲染引擎【☆】
GUI渲染线程(渲染页面)
JS引擎线程
GUI渲染与JS引擎线程运行‘互相排斥’
5.渲染进程-GUI
解析HTML、csss
构建DOM、Render树
初始布局与绘制
重绘与回流
--事件
事件触发线程:事件环Event loop
事件线程:用户交互事件、setTimeout、Ajax
--宏任务微任务
宏任务:【宿主(浏览器、node)】提供的异步方法和任务
script、setTiomeout UI渲染
微任务:【ES】提供的API运行
Promise mutationsObserver
二、图解Event loop
//eg1:
Promise.resolve().then(() => {
console.log('p1');
setTimeout(() => {
console.log('s2');
}, 0)
})
setTimeout(() => {
console.log('s1');
Promise.resolve().then(() => {
console.log('p2');
})
})
/**
* 执行栈:
* promise1.then cb ==> p1
* setTimeout1 cb ==> s1
* promise2.then cb ==> p2
* setTimeout2 cb ==> s2
* 宏任务: setTimeout1 x setTimeout2 x
* 回调队列 setTimeout1 cb x setTimeout2 cb x
*
* 微任务: Promise1 x promise2 x
* 回调队列 Promise1.then cb x promise2.then cb x
*
*
*/
// eg1【扩展】
Promise.resolve().then(() => {
console.log('p1');
setTimeout(() => {
console.log('s2-1');
}, 0)
setTimeout(() => {
console.log('s2-2');
}, 0)
})
setTimeout(() => {
console.log('s1');
Promise.resolve().then(() => {
console.log('p2-1');
}).then(() => {
console.log('p2-2');
})
})
/**
* JS执行栈
* promise1 cb ==> p1
* setTimeout1 cb ==> s1
* promise2 cb ==> p1-1
* promise3 cb ==> p2-2
* sto2 cb ==> s2-1
* sto3 cb ==> s2-2
* 宏任务: setTimeout1 x sto2 x sto3 x
* 回调: setTimeout1 cb x sto2 cb x cto3 cb x
* 微任务: promise1 x promise2 x promise3 x
* 回调: promise1 cb x promise2 cb x promise3 cb x
*/
// eg2
console.log(1);
setTimeout(() => {
console.log(2);
}, 10)
new Promise(function (resolve, reject) {
console.log(3);
resolve('')
console.log(4);
}).then(res => {
console.log(5);
})
console.log(6);
/**
* JS执行栈
* 1
* 3
* 4
* 6
* promise.then cb ==>5
* setTimeout cb ==>2
* 异步宏任务 setTimeout x
* 回调 setTimeout cb x
* 异步微任务 Promise x
* 回调 promise.then cb x
*
*/
// eg2【扩展】❤坑❤==> 宏任务队列里面 拿取顺序要看setTimeout的执行时间 时间短的先拿
console.log(1);
setTimeout(() => {
Promise.resolve().then(() => {
console.log(2);
})
}, 10)
new Promise(function (resolve, reject) {
console.log(3);
resolve('')
console.log(4);
}).then(res => {
setTimeout(() => {
console.log(5);
}, 0)
})
console.log(6);
/**
* JS执行栈
* 1
* 3
* 4
* 6
* setTimeout cb ==> 5
* promise2 cb ==> 2
* 宏任务 setTimeout1 setTimeout2 x
* setTimeout1 cb setTimeout cb x
*
* 微任务 Promise1 x promise2
* Promise1 cb x promise2 cb
*/
注意:
asnyc函数 会返回一个Promise实例 await函数 必须存在asnyc函数中
// eg3
let res = function () {
console.log(1);
return new Promise((resolve, reject) => {
console.log(2);
resolve(4)
})
}
new Promise(async (resolve, reject) => {
console.log(3);
let test = await res() //所以此时test是一个【微任务】 但是这个时候会调用test函数
/**
* await res() ===> res().then((test)=>{
* console.log(test);
* })
*/
console.log(test);
})
console.log(5);
new Promise((resolve, reject) => {
console.log(6);
})
console.log(7);
/**
* js执行栈
* res = function () {} //只赋值 不执行 此时 res是一个Promise实例
*
* 3
* 1
* 2
* 5
* 6
* 7
* 4 //这个4是微任务 要等所用同步执行完成后才执行
* 宏任务:
*
* 微任务: awaitPromise x
* awaitPromise cb x
*/
// eg3【超级扩展】
let res = function () {
console.log(1);
return new Promise((resolve, reject) => {
setTimeout(() => { //s2
new Promise((resolve) => {
console.log(2);
setTimeout(() => { //s5
console.log(3);
})
})
}, 0)
resolve(5)
})
}
new Promise(async (resolve, reject) => {
setTimeout(() => { //s1
Promise.resolve().then(() => { //p2
console.log(4);
})
}, 0)
let test = await res()//awaitPromsie1 //所以此时test是一个【微任务】 但是这个时候会调用test函数
/**
* await res() ===> res().then((test)=>{
* console.log(test);
* })
*/
console.log(test);
})
setTimeout(() => { //s3
console.log(6);
}, 0)
new Promise((resolve, reject) => {
setTimeout(() => { //s4
console.log(7);
}, 0)
})
console.log(8);
/**
* JS 执行栈
* res = function () {} //不执行
* 1
* 8
* 5
* 4
* 2
* 6
* 7
* 3
* 宏任务 setTimeout1 x setTimeout2 x setTimeout3 x setTimeout4 7 s5
* setTimeout1 cb x setTimeout2 cb x setTimeout3 cb x setTimeout4 cb 7 s5 cb
* 微任务 awaitPromsie1 x Promsie2 x Promsie3 x
* awaitPromsie1 cb x Promsie2 cb x Promsie3 x
*/
交互事件(宏任务)
//eg4
const oBtn = document.getElementById('btn');
oBtn.addEventListener('click', () => {
console.log(1);
Promise.resolve('m1').then((str) => {
console.log(str);
})
}, false)
oBtn.addEventListener('click', () => {
console.log(2);
Promise.resolve('m2').then((str) => {
console.log(str);
})
}, false)
oBtn.click()
/**
* 当我用js调用click() 函数的时候: //1 2 m1 m2
* 同时执行m1 m2 两个宏任务】 并创建了两个微任务==>依次清空微任务
当用户点击调用的时候: //1 m1 2 m2
按照上下顺序 先后监听 先执行m1宏任务 =>创建promise1微任务=>清除微任务
先执行m2宏任务 =>创建promise2微任务=>清除微任务
*/
setInterval (在没遇到清除定clearInterval的时候 会一直执行setInterval)
// eg5 在浏览器中,`setTimeout()`setInterval 的每调用一次定时器的最小间隔是 4ms ***
console.log('start');
const interval = setInterval(() => {
console.log('setInterval');
}, 0)
setTimeout(() => { //s1
console.log('settimeout 1');
Promise.resolve()
.then(() => { //p2
console.log('promise 3');
})
.then(() => { //p3
console.log('promise 4');
})
.then(() => { //p4
setTimeout(() => { //s2
console.log('settimeout 2');
Promise.resolve()
.then(() => { //p5
console.log('promsie 5');
})
.then(() => { //p6
console.log('promsie 6');
})
.then(() => { //p7
clearInterval(interval)
})
}, 0)
})
}, 0)
Promise.resolve()
.then(() => { //p1
console.log('promsie 7');
})
/**
* JS执行栈
* start
* p1 cb ==> promsie 7
* setInterval cb ==> setInterval
* s1 cb ==> settimeout 1
* p2 cb ==> promise 3
* p3 cb ==> promise 4
* p4 cb ==>
* setInterval cb ==> setInterval
* s2 cb ==> settimeout 2
* p5 cb ==> promsie 5
* p6 cb ==> promsie 6
* p7 ==> 清除定时器 不打印
* 宏任务
* setInterval x
* setInterval cb x
* s1 x
* s1 cb x
* setInterval x
* setInterval cb x
* s2 x
* s2 cb x
* setInterval x 清除定时器 不打印
* setInterval cb x 清除定时器 不打印
* 微任务
* p1 x
* p1 cb x
* p2 x
* p2 cb x
* p3 x
* p3 cb x
* p4 x
* p4 cb x
* p5 x
* p5 cb x
* p6 x
* p6 cb x
* p7 x
* p7 cb x
*
*
*/
// eg6
setTimeout(() => { //s1
console.log('setTimeout1');
setTimeout(() => {//s3
console.log('setTimeout3');
}, 1000)
Promise.resolve().then(data => {//p4
console.log('then3');
})
}, 1000)
Promise.resolve().then(() => { //p1
console.log('then1');
console.log('then4');
Promise.resolve().then(data11 => {//p3
console.log('then6');
})
})
Promise.resolve().then(() => { //p2
console.log('then2');
console.log('then5');
setTimeout(() => {//s2
console.log('setTimeout2');
}, 1000)
})
console.log(2);
/**
* JS执行栈
* 2
* p1.then cb ==> then1
* then4
* p2.then cb ==> then2
* then5
* p3.then cb ==> then6
* s1 cb ==> setTimeout1
* p4.chen cb ==> then3
* s2 cb ==> setTimeout2
* s3 cb ==> setTimeout3
*
* 宏任务
* s1 x
* s1 cb x
* s2 x
* s2 cb x
* s3 x
* s3 cb x
* 微任务
* p1 x
* p1.then cb x
* p2 x
* p2.then cb x
* p3 x
* p3.then cb x
* p4 x
* p4.then cb x
*/