Skip to content

新技术合集

Web Worker

印象很深的一道面试题,也是我老大在面试我的时候问的。

老大:如何让 setTimeout 或着 setInterval 在时间传 0 就能立即执行。

我:巴拉巴拉... 答错了

老大:这题的意义是想看下你对新技术有没有了解,你可以了解一下 Web Worker

我:这个我知道!(马后炮)

虽然我看了红宝书、犀牛书、都有读到关于 Web Worker 的内容,但是也没有自己去动手写过代码,只知道这玩意儿能单独开一个线程,并且它拥有一系列的特点,通过这个面试题,也让我意识到,有时候自己是属于一个 “死读书” 的状态,并没有真的理解一个技术,或者一个 API 的作用。原因如下:

如果我老大直接问我:Web Worker 是干啥的,有啥作用,有啥特点? 我相信我读了蛮多的书能回答出老大觉得及格的答案。而我的老大是简单的逆向的问我一下,我就回答不出来了。此谓:“死读书”。

言归正传,下面开始讲讲 Web Worker

什么是 web Worker

我们都知道 JS 的单线程的,一次只能做一件事情,所以 JS 才会使用“异步(非阻塞)”的方式做一些网络请求等耗时的任务,因为如果是同步执行网络请求的话情况下,在执行网络请求的过程中,就会终止浏览器主进程的解析,有可能出现页面白屏等情况,造成不好的用户体验。

为了更好的发挥 CPU 的多核资源,所以我们可以在主线程之外再创建一个线程!利用这个线程去做一些操作!

子线程的特点

因为我们使用了多线程,所以必须知道多线程具有的优点:

  • 多线程技术使程序的响应速度更快 ,因为用户界面可以在进行其它工作的同时一直处于活动状态;
  • 占用大量处理时间的任务使用多线程可以提高 CPU 利用率,即占用大量处理时间的任务可以定期将处理器时间让给其它任务;
  • 多线程可以分别设置优先级以优化性能。

以上的内容都是百度的,当然最重要的点都离不开前端非常关键的词:“性能

使用场景

  • 解析文本(markdown 转 html)

    曾经做过的一个个人博客,需要将 markdown 转成 html 字符串再渲染,当 markdown 文档特别大的时候,这个计算过程就会相对比较久,这个就是使用离我最近的一个 使用场景 !

  • 复杂的运算

  • 流媒体等操作

    B 站的视频有用到这个

基本使用

html
<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta http-equiv="X-UA-Compatible" content="IE=edge" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>webworker</title>
	</head>
	<body>
		<script src="./index.js"></script>
	</body>
</html>
<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta http-equiv="X-UA-Compatible" content="IE=edge" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>webworker</title>
	</head>
	<body>
		<script src="./index.js"></script>
	</body>
</html>
js
// index.js
const worker = new Worker('worker.js')
// console.log(1)

worker.onmessage = e => {
	console.log('接收到了消息', e)
}

setInterval(() => {
	console.log('old console')
}, 1000)

worker.postMessage('给子线程')
setTimeout(() => {
	// 2秒后开启一个阻塞主线程的任务, webworker子线程并不会被阻塞住
	confirm('理解webworker了吗 看看控制台')
}, 2000)

// worker.js
onmessage = e => {
	console.log('接收到了', e)
}

setInterval(() => {
	console.log('过了一秒了')
}, 1000)

postMessage('hello world by hello world')
// index.js
const worker = new Worker('worker.js')
// console.log(1)

worker.onmessage = e => {
	console.log('接收到了消息', e)
}

setInterval(() => {
	console.log('old console')
}, 1000)

worker.postMessage('给子线程')
setTimeout(() => {
	// 2秒后开启一个阻塞主线程的任务, webworker子线程并不会被阻塞住
	confirm('理解webworker了吗 看看控制台')
}, 2000)

// worker.js
onmessage = e => {
	console.log('接收到了', e)
}

setInterval(() => {
	console.log('过了一秒了')
}, 1000)

postMessage('hello world by hello world')

通过这个简单的例子我就大概能明白 web worker 的优势了!

pnpm

pnpm 是一个新的包管理工具,它最大的提示是解决了幽灵依赖的问题。

幽灵依赖:项目中可以使用 package.json 定义以外的包!(一些包可能依赖于其他的包)在 yarn 安装模式下,会将所有的包都进行一次排平处理(所有包都在同一级文件下)。所以在启动时能使用那些包,不报错

而 pnpm 使用软链接的方式,所有下载的包都在.pnpm 下,而外层则是一些文件的软链接(本身也不占空间),所以能够做到不会浪费资源且不能使用未定义的包。