webworker使用介绍,js中开启多线程

【Webworker】

注:必须要在服务器环境。

什么是webworker?
Web Worker为Web应用程序提供了一种能在后台中运行的方法。通过Web Worker可以生成多个线程同时运行,并保证页面对用户的及时响应,完全不会影响用户的正常操作。

单线程:单线程在程序执行时,所走的程序路径按照连续顺序排下来,前面的必须处理好,后面的才会执行。简单的说就是处理事务的任务链,当只有一条链,所有的事情都在这一条链上执行时,那就是单线程。

优点:单线程较多线程来说,系统稳定、扩展性极强、软件丰富。

缺点:只有一个线程,代码顺序执行,容易出现代码阻塞(页面假死)。

多线程:有多条链时,那就是多线程了,当然并不是说多条线并行,而是说有一条主线程,处理整个程序任务的主方向的链,而其链上又有许许多多的分支,就像树枝那样,这样,既有了主线程去处理那些主要任务,又有了那些细小线程去处理耗时费力任务,从而让界面看起来更加流畅。

不容置疑的事实是:Javascript是单线程的,基于其特殊的用途,为了避免复杂性,从一开始,JavaScript就是单线程,这已经成了这门语言的核心特征,将来也不会改变。所以一定要明确这一点,同时也要理解对这个单线程的概念,理解不好就容易糊涂。JS的单线程是指一个浏览器进程中只有一个JS的执行线程,同一时刻内只会有一段代码在执行,但是浏览器有很多线程,是多线程的,当js线程在执行时,浏览器可以根据需求开相应的线程进行处理。

那能不能开启js的多线程?
可以,html5的webworker允许javascript多线程。

多线程是在原有主线程之外分了worker线程出来,但是子线程完全受主线程控制,且不得操作DOM。因为Worker线程不能直接访问和操作页面中的DOM属性,如果Worker线程需要访问页面中的某个DOM节点,必须通过postMessage API发消息给主线程,主线程在收到消息后获取页面中的某个DOM节点的属性,再通过postMessage的方式回传给Worker线程,这样就避免了冲突。

那么怎么使用webworker多线程呢?

首先说一下webworker使用的代码说明:

WEB主线程:

1.通过 worker = new Worker( url ) 加载一个JS文件来创建一个worker,同时返回一个worker实例。

2.通过worker.postMessage( data ) 方法来向worker发送数据。

3.绑定worker.onmessage方法来接收worker发送过来的数据。

4.可以使用 worker.terminate() 来终止一个worker的执行。

worker子线程:

1.通过postMessage( data ) 方法来向主线程发送数据。

2.绑定onmessage方法来接收主线程发送过来的数据。

开始编写程序

1)创建一个Worker:

通常,与web worker相关的代码都放在一个独立的JavaScript文件中。父线程通过在Worker构造函数中指定一个JavaScript文件的链接来创建一个新的worker,它会异步加载并执行这个JavaScript文件。

//var oW = new Worker(子线程路径);
//var oW = new Worker('a.js');
//console.log(oW); //对象 身上有很多数据

var oW = new Worker('a.js'); //创建
oW.postMessage('12');  //方法来向worker发送数据。

2)编写子线程a.js:

this.onmessage = function(ev){
    console.log(ev.data);  // html页面输出12   注:子线程没有alert
};

//*********************************

this.onmessage = function(ev){
    console.log(typeof ev.data);  //html页面输出string  注意:传过来数据形式是什么接受就是什么。
};

注意:

1.子线程进行计算,不能进行 DOM BOM操作
2.子线程不能跨域,文件需放在同路径中
3.子线程不能套子线程
4.子线程 不和主线程共享数据,而是复制一份儿 哪怕是对象

子线程可以直接输入运算:

//主线程html页面
var oW = new Worker('b.js');
oW.postMessage(alert);

//子线程b.js
this.onmessage = function(ev){
console.log(ev.data+5);    //  10  
};

可以利用子线程为我们做一些计算:

var oW = new Worker('c.js');
oW.postMessage(12);  //向子线程发送数据
oW.onmessage = function(ev){ //接收字线程发送过来的数据
alert(ev.data);  //17
};

//子线程c.js
this.onmessage = function(ev){  //接收主线程发送过来的数据
this.postMessage(ev.data+5);  //向主线程发送数据
};

子线程不和主线程共享数据,而是复制一份儿,哪怕是对象:

变量:

//主线程html页面
var oW = new Worker('d.js');
var a = 12;
oW.postMessage(a);
oW.onmessage = function(ev){
    alert(ev.data);//17
};
alert('主线程:'+a); //12

//子线程d.js
this.onmessage = function(ev){
    this.postMessage(ev.data+5);
};

对象:

//主线程html页面
var oW = new Worker('e.js');
var arr = [12,5,8];
oW.postMessage(arr);
oW.onmessage = function(ev){
    alert('子线程'+ev.data);//[101,5,8]
};
alert('主线程'+arr);//12,5,8

//子线程e.js
this.onmessage = function(ev){
    ev.data[0] = 101;
    console.log(ev.data);
    this.postMessage(ev.data);
};

那么怎么测试到底有没有是多线程?如果确定子线程是否运行呢?

那么我就说一下我的思路:
1、先写一个可以让程序进入暂时性假死状态的函数,

function fn(n){ //写一个可以让程序假死的函数
    if(n<=2){
        return 1;  // 如果我们传进来的小于等于2 就走这个。
    }else{
        return fn(n-2)+fn(n-1);  //如果我们传进来的大于2,就一直自动的持续调用自己,直到小于2。这样可以让系统进入假死状态,需要处理很长时间才结束。
    }
}

2、然后写出四个按钮,
第一个点击后,直接传入一个大一2的数,调用函数,让程序假死。
第二个点击后,会调用一个子线程,子线程里面有同样的函数,也来执行调用。
第三个点击后:出测试结果后,直接中断子线程,等的时间确实长。。你懂得。。
第四个点击后:页面正常弹1
3、开始写子线程

//和主线程同样的函数
function fn(n){
    if(n<=2){
        return 1;
    }else{
        return fn(n-2)+fn(n-1);
    }
}
this.onmessage = function(ev){
    this.postMessage(fn(ev.data));  //给主线程返回调用函数处理后的数据
};

4、开始编写页面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>前端开发工程师-李鹏</title>
    <style>

    </style>
    <script>
function fn(n){ //写一个可以让程序假死的函数
    if(n<=2){
        return 1;  // 如果我们传进来的小于等于2 就走这个。
    }else{
        return fn(n-2)+fn(n-1);  //如果我们传进来的大于2,就一直自动的持续调用自己,直到小于2。这样可以让系统进入假死状态,需要处理很长时间才结束。
    }
}
        document.addEventListener('DOMContentLoaded',function(){
            var aBtn = document.querySelectorAll('input');
            var oW;//因为要做四个点击按钮,所以让线程为全局变量
            aBtn[0].onclick = function(){ //点击的时候 直接调用函数 让程序假死,然后点击第四个按钮,测试看看能不能弹1
                alert(fn(48));
            };
            aBtn[1].onclick = function(){ //点击的时候让子线程来执行这个 同样的函数,然后点击第四个按钮,测试看看能不能弹1
                oW = new Worker('fib.js');
                oW.postMessage(48);
                oW.onmessage = function(ev){alert(ev.data);};
            };
            aBtn[2].onclick = function(){ //测试成功后就用来终止子线程,,因为等待时间确实长。。你懂得
                oW.terminate();
            };
            aBtn[3].onclick = function(){  //作为测试函数。
                alert(1);
            };

        },false);


    </script>
</head>
<body>
<input type="button" value="开启主线程">
<input type="button" value="开启子线程">
<input type="button" value="关闭进程">
<input type="button" value="测试">
</body>
</html>

结果:
点击第一个后,直接执行假死函数,让程序假死,在点击第四个按钮,没有作用,不会立即弹1,只有等待很长时间之后假死函数执行完毕后, 才会弹1。
点击第二个后,让子线程来执行假死函数,让程序假死,在点击第四个按钮,直接就会立即弹1,随时点,随时弹,等待很长时间后假死函数执行完毕后,弹结果。
可以复制自己去测试。
以上结束。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,198评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,663评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,985评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,673评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,994评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,399评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,717评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,407评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,112评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,371评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,891评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,255评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,881评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,010评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,764评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,412评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,299评论 2 260

推荐阅读更多精彩内容

  • 最近在阅读这本Nicholas C.Zakas(javascript高级程序设计作者)写的最佳实践、性能优化类的书...
    undefinedR阅读 2,140评论 0 30
  • Object C中创建线程的方法是什么?如果在主线程中执行代码,方法是什么?如果想延时执行代码、方法又是什么? 1...
    AlanGe阅读 1,661评论 0 17
  • 官方中文版原文链接 感谢社区中各位的大力支持,译者再次奉上一点点福利:阿里云产品券,享受所有官网优惠,并抽取幸运大...
    HetfieldJoe阅读 2,297评论 1 21
  • 云拨天开,短影照,滚烫了满园气息空苍穹; 潮起潮落,影绰绰,荡开了阔道闲木守孤钟; 忧念沉浮,为寻忆,停驻的背后依...
    三水R阅读 180评论 0 1
  • 最近打《王者荣耀》我全部用的庄周。打了有五六十场了,越打越顺手。庄周不像射手也不像战士或者刺客专门的收人头、专门推...
    一叶茶阅读 558评论 0 1