单线程,指的是只有一个线程,同一时间只能做一件事。JS 使用单线程的主要原因是避免 DOM 渲染的冲突,它的解决方法就是异步。
下面的例子可以体会一下 JS 单线程:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
</body>
<script>
// 循环运行期间,JS 执行和 DOM 渲染暂时卡顿
console.log('start')
var i, sum = 0;
for (i = 0; i < 100000000; i++) {
sum += i;
}
console.log(sum);
// alert 不处理,JS 执行和 DOM 渲染暂时卡顿
console.log(1)
alert('hello')
console.log(2)
</script>
</html>
上面的例子中,如果打开调试面板,可以明显看到如果 for 循环未结束的话,后面的 console.log(sum)
是不会执行的。
另外还有地 23 行中,如果 alert
未确认,后面的 console.log(2)
也不会执行。
为什么 JS 是单线程?
JS 使用单线程其主要原因是要避免 DOM 渲染冲突。
首先先明确两点:
- 浏览器需要渲染 DOM
- JS 也可以修改 DOM 结构
由于浏览器和 JS 都会触及到 DOM,如果浏览器和 JS 都同时涉及到 DOM 操作的话,那就会产生冲突了。因此在 JS 执行的时候,浏览器 DOM 渲染就会暂停。
两段 JS 代码也不能同时执行,如果两端 JS 代码都修改 DOM,如果同时执行的话,也是会产生冲突的。所以需要先执行完一段 JS 代码之后,才会执行另一段 JS 代码。
因此 JS 在浏览器中应用必须是单线程的,而且与浏览器渲染共用一个进程。
虽然 H5 中的 webworker 支持多线程,但是不能访问 DOM。程序