概念与API


webworker


  • Web Workers 是 HTML5 提供的一个javascript多线程解决方案
  • 我们可以将一些大计算量的代码交由web Worker运行而不冻结用户界面
  • 但是子线程完全受主线程控制,且不得操作DOM。所以,这个新标准并没有改变JavaScript单线程的本质

API


我们只需要记住三个API就可以了

  1. new Worker()创建一个worker对象
  2. postMessage(data)向主线程发送数据
  3. onmessage=fun(event),监听发送的分线程发送的数据,通过event.data取出

使用


使JS创建斐波那契数列


什么是斐波那契数列


例如下面这一列数

1,1,2,3,5,8//第一个数 + 第二个数 = 第三个数,有这样一个规律的一列数,就叫做斐波那契数列

使用JS写斐波那契数列


/* 斐波那契数列实际上是一个递归调用的函数,n表示处于数列的第几位树 */
//1 1 2 3 5 8 
function fibonacci(n){
	return n<=2 ? 1 : fibonacci(n-1) + fibonacci(n-2)
}

效果

现在我们做一个这样的效果,在输入框中输入斐波那契数列的第几位数,提示出这个位上的数字是多少

<input type="text" id="number" />
<button type="button" id="btn">获取数据</button>
<script type="text/javascript">
	/* 斐波那契数列实际上是一个递归调用的函数,n表示处于数列的第几位树 */
	//1 1 2 3 5 8 
	function fibonacci(n){
		return n<=2 ? 1 : fibonacci(n-1) + fibonacci(n-2)
	}
	const input = document.getElementById("number")
	document.getElementById("btn").onclick = function(){
		const number = input.value
		const result = fibonacci(number)
		alert(result)
	}
</script>
  • 当我们输入6的时候,浏览器很快就给我们显示出是8
    在这里插入图片描述
  • 但是当我们输入45的时候,界面好像卡住了一样,等了将近半分钟才出现结果,这时为什么呢?

在这里插入图片描述
原因分析

我们写的斐波那契数列相当于递归调用,而递归的效率比较低

  • 递归调用的本质是函数的嵌套调用,在执行上下文栈中,在存储的函数会特别多,需要一个一个的去调用这些函数
  • 我们输入的值越大,嵌套的层数也就越深,需要的时间也就越长
  • 而此代码属于初始化代码,他是在JS主线程执行的,主线程在调用函数,也就不能做其他的是

使用分线程


我们可以利用webworker,将递归调用那一部分交给分线程处理,他的步骤如下

  1. 新建一个JS文件代表分线程
  2. 将需要执行的程序放到分线程执行,结构固定
  3. 分线程文件中调用postMessage将结果发送到主线程
  4. 主线程调用onmessage进行监听

主线程

<input type="text" id="number" />
<button type="button" id="btn">获取数据</button>
<script type="text/javascript">
	const input = document.getElementById("number")
	document.getElementById("btn").onclick = function(){
		const number = input.value
		/* 新建worker实例,注意传入分线程路径 */
		const worker = new Worker('worker.js')
		/* 监听postMessage */
		worker.onmessage = function(event){
			console.log("主线程接收到分线程返回的数据" + event.data)
			alert(event.data)
		}
		/* 想分线程发送消息 */
		worker.postMessage(number)
		console.log('主线程向分线程发送数据' + number)
	}
</script>
  • 我们在相同目录下新建worker.js,将递归调用的函数拉到了分线程中
/* 将进行递归调用的函数移到分线程来 */
function fibonacci(n) {
	return n <= 2 ? 1 : fibonacci(n - 1) + fibonacci(n - 2)
}
this.onmessage = function(event){
	const number = event.data
	console.log('接收到主线程发送的数据' + number)
	/* 调用占用时间的函数 */
	const result = fibonacci(number)
	/* 将数据发送到主线程 */
	postMessage(result)
	console.log("分线程想主线程返回数据" + result)
}

当我们在输入45 的时候,我们会发现,界面不会被冻结,而等片刻之后,他会向我们返回数据

在这里插入图片描述

其他说明


this的说明


在分线程的JS文件中,this的指向不在是window,而是一个新的对象
在这里插入图片描述

缺点


  • worker内代码不能操作DOM更新UI
  • 不是每个浏览器都支持这个新特性
  • 不能跨域加载JS
Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐