一、JS引擎线程面试题(执行顺序)
结果:1,2,4,8,5,6,3,7
解析:
二、JS引擎线程和GUI渲染线程的实例
JS代码执行和GUI渲染过程,下面是验证一下该过程
所有的同步宏任务执行完--->所有微任务执行完--->渲染页面--->执行完任务队列中的一个宏任务--->所有微任务执行完--->渲染页面--->任务队列中的一个宏任务-->所有微任务-->渲染页面......
1、<script></script>标签中的同步任务都是宏任务,执行完,看是否有微任务,没有则渲染页面;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div>123</div>
<input type="button" onclick="(()=>{
console.log(6)
})()" />
<!-- script是一个宏任务 -->
<script>
document.body.style.background = 'red';
// 1
setTimeout(()=>{
console.log(2222);
let a = 0
for(let i=0;i<10000000000;i++){
a++
}
document.body.style.background = 'blue';
},0)
</script>
</body>
</html>
现象:进入页面先红色,再过段时间变成蓝色;
结论:所有的同步宏任务执行完-->所有微任务执行完(上面代码没有微任务,跳过)-->渲染页面-->
2、<script></script>标签中的同步任务都是宏任务,执行完,看是否有微任务,有执行完所有微任务,再渲染页面;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div>123</div>
<input type="button" onclick="(()=>{
console.log(6)
})()" />
<!-- script是一个宏任务 -->
<script>
document.body.style.background = 'red';
//2
Promise.resolve().then(()=>{
console.log(11111);
let a = 0
for(let i=0;i<10000000000;i++){
a++
}
document.body.style.background = 'yellow';
});
</script>
</body>
</html>
现象:进入页面先是空白,等所有微任务执行完,页面只会显示黄色
结论:所有的同步宏任务执行完-->所有微任务执行完(有微任务,执行微任务,yellow会覆盖掉red,所以页面只会是黄色)-->渲染页面-->
3、<script></script>标签中的同步任务都是宏任务,执行完,任务队列既有宏,又有微任务,看一下结果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div>123</div>
<input type="button" onclick="(()=>{
console.log(6)
})()" />
<!-- script是一个宏任务 -->
<script>
document.body.style.background = 'red';
// 1
setTimeout(()=>{
console.log(2222);
let a = 0
for(let i=0;i<10000000000;i++){
a++
}
document.body.style.background = 'blue';
},0)
// 2
Promise.resolve().then(()=>{
console.log(11111);
let a = 0
for(let i=0;i<10000000000;i++){
a++
}
document.body.style.background = 'yellow';
});
// // 3
Promise.resolve().then(()=>{
console.log(11112222);
let a = 0
for(let i=0;i<1000000000;i++){
a++
}
document.body.style.background = 'purple';
});
// // 4
setTimeout(()=>{
console.log(33333);
let a = 0
for(let i=0;i<1000000000;i++){
a++
}
document.body.style.background = 'orange';
},0)
</script>
<script>
</script>
</body>
</html>
现象:进入页面先是空白,然后是页面是purple(紫色),后面显示blue(蓝色),最后显示orange(橘黄色)
结论:所有的同步宏任务执行完-->所有微任务执行完(有微任务,执行所有微任务,purple会覆盖掉red和上一个微任务yellow,所以页面空白后显示purple(紫色))-->渲染页面--> 宏任务队列执行完一个宏任务(blue(蓝色))-->没有微任务了-->渲染页面-->宏任务队列执行完一个宏任务(orange(橘黄色))-->没有微任务了-->渲染页面;
最终页面显示橘黄色;
4、<script></script>标签本身就是一个宏任务
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div>123</div>
<input type="button" onclick="(()=>{
console.log(6)
})()" />
<!-- script是一个宏任务 -->
<script>
document.body.style.background = 'red';
Promise.resolve().then(()=>{
console.log(11111);
let a = 0
for(let i=0;i<10000000000;i++){
a++
}
document.body.style.background = 'yellow';
});
</script>
<script>
console.log(22222);
let a = 0
for(let i=0;i<10000000000;i++){
a++
}
document.body.style.background = 'orange';
</script>
</body>
</html>
现象:进入页面先是空白,等所有微任务执行完,页面先显示黄色,最重显示橘黄色;
结论:所有的同步宏任务执行完-->所有微任务执行完(有微任务,执行所有微任务,yellow会覆盖掉red,所以页面空白后显示yellow(黄色))-->渲染页面--> 宏任务队列执行完下一个宏任务(<script></script>里面的同步宏任务代码,orange(橘黄色))-->没有微任务了-->渲染页面;
最终页面显示橘黄色;