H5 Web Worker 使用
API我们只需要记住三个API就可以了new Worker()创建一个worker对象postMessage(data)向主线程发送数据onmessage=fun(event),监听发送的分线程发送的数据,通过event.data取出使用使JS创建斐波那契数列什么是斐波那契数列例如下面这一列数1,1,2,3,5,8…//第一个数 + 第二个数 = 第三个数,有这样一个规律的一列数,就叫做斐波那契数
·
概念与API
webworker
- Web Workers 是 HTML5 提供的一个javascript多线程解决方案
- 我们可以将一些大计算量的代码交由web Worker运行而不冻结用户界面
- 但是子线程完全受主线程控制,且不得操作DOM。所以,这个新标准并没有改变JavaScript单线程的本质
API
我们只需要记住三个API就可以了
new Worker()
创建一个worker对象postMessage(data)
向主线程发送数据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,将递归调用那一部分交给分线程处理,他的步骤如下
- 新建一个JS文件代表分线程
- 将需要执行的程序放到分线程执行,结构固定
- 分线程文件中调用
postMessage
将结果发送到主线程 - 主线程调用
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
更多推荐
已为社区贡献5条内容
所有评论(0)