PHPIN.NET

 找回密码
 立即注册
查看: 4853|回复: 0

[实例分享] javascript 实现多线程

[复制链接]

469

主题

31

回帖

5507

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
5507
发表于 2018-5-28 12:41:37 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
javascript 实现多线程

在讲之前,大家都知道js是基于单线程的,而这个线程就是浏览器的js引擎。
首先来看一下大家用的浏览器都具有那些线程吧。

javascript 实现多线程.png

假如我们要执行一些耗时的操作,比如加载一张很大的图片,我们可能需要一个进度条来让用户进行等待,在等待的过程中,整个js线程会被阻塞,后面的代码不能正常运行,这可能大大的降低用户体验,这时候我们就期望拥有一个工作线程来处理这些耗时的操作。在传统的html时代是基本不可能实现的,而现在,我们拥有一种叫做worker的东西。它是js里的一个类,而我们只需要创建它的实例就可以使用它。
  1. var worker = new Worker(js file path);
复制代码
构造函数的参数填上你的js文件的路径,这个js文件将会在浏览器新开的线程里运行,而与原先的js引擎的线程并不影响。
下面看个例子。
  1. <!DOCTYPE html>
  2. <html>
  3.     <head>
  4.         <meta charset="utf-8" />
  5.         <title></title>
  6.     </head>
  7.     <body>
  8.         <input type="text" name="ipt" id="ipt" value="" />
  9.         <button id="start">start</button>
  10.         <button id="stop">stop</button>
  11.         <button id="ale">alert</button>
  12.         <script type="text/javascript">
  13.             var ipt = document.getElementById("ipt");
  14.             var stop = document.getElementById("stop");
  15.             var start = document.getElementById("start");
  16.             var ale = document.getElementById("ale");
  17.             var worker = new Worker("test.js");
  18.             worker.onmessage = function(){
  19.                 ipt.value = event.data;
  20.             };
  21.             stop.addEventListener("click",function(){
  22.                 //用于关闭worker线程
  23.                 worker.terminate();
  24.             });
  25.             start.addEventListener("click",function(){
  26.                 //开起worker线程
  27.                 worker = new Worker("test.js");
  28.             });
  29.             ale.addEventListener("click",function(){
  30.                 alert("i'm a dialog");
  31.             });
  32.         </script>
  33.     </body>
  34. </html>
复制代码
下面是test.js里的代码,也就是存在于worker线程里的代码
  1. var i = 0;
  2. function mainFunc(){
  3.     i++;
  4.     //把i发送到浏览器的js引擎线程里
  5.     postMessage(i);
  6. }
  7. var id = setInterval(mainFunc,1000);
复制代码
运行起来我们会发现

demo1.png

点击确定后,它的数值并非2,而是一个比2更大的数

demo2.png

虽然dialog的弹出会阻塞js引擎线程,但是并不影响worker线程的运行,所以,在我们点击确定后,只是在js引擎线程上更新了新的内容,而数值是一直在跑动的,这就说明worker线程和原本的js线程互不影响.

那么既然互不影响,两个线程之间要怎么来联系呢,答案其实已经在代码里了,那就是onPostMessage 和 onmessage这两个函数,其中onPostMessage(data)的参数是你要传递的数据,而onmessage是一个回调函数,只有在接受到数据时,onmessage会被回调,onmessage有一个隐藏的参数,那就是event,我们可以用event.data获取到传递过来的数据来更新主线程。

使用worker线程应注意的是,所有js里集成的对象都在js线程里,而并非worker线程。
例如我们在worker线程里写上:
  1. var a = document.getElementById("a");
复制代码
结果你会得到一条Error,告诉你找不到document,或者document is undefined。所以我们尽量把需要的东西都写到主线程里,而只把耗时的操作写到worker线程里。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|PHPIN.NET ( 冀ICP备12000898号-14 )|网站地图

GMT+8, 2024-4-19 18:02

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表