HTML5 Web Workers、Socket之网站也能多线程的实现

现在由于Web开发的需求越来越广泛,异步请求和并发、预处理等等都是提高了对网页处理复杂的业务能力和大数据的需求,所以有了很多高并发和异步处理的插件和方式出来,自从HTML5出来也带来很大的进步、改变,下面我们就来说说Web Workers和Web Socket的好处。

一、Web Workers是在HTML5中新增的,用来在web应用程序中实现后台处理的一种技术。

在HTML4中,js创建的程序都是单线程的,如果花费时间比较长的话web界面就会长时间没有响应,最恶劣的情况还会跳出一个脚本提示框:

提示脚本运行时间过长,是否继续。。。。于是就引出了本文的主角:Web Workers API

你可以在你的 worker 线程中运行任意的代码,以下情况除外:你不能直接在 worker 线程中操纵 DOM 元素, 或者使用某些 window 对象中默认的方法和属性。 但是 window 对象中很多的方法和属性你是可以使用的,包括 WebSockets,以及诸如 IndexedDB 和 FireFox OS 中独有的 Data Store API 这一类数据存储机制。

使用这个API用户可以非常容易的创建在后台运行的线程,要创建后台程序很简单:

var worker = new Worker('*.js');
注意:后台线程是不能访问页面或者窗口对象的
可以通过发送消息和接受消息与后台线程传递数据:
worker.onmessage = function (e) {};
worker.postMessage = function (e) {};

1.接下来我们测试一个简单的求和例子,先来一个普通大众的求和方法:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script type="text/javascript">
function calculate() {
    var num = 10000000000;
    var r = 0;
    for (var i = 1; i < num; i++) {
        r += i;
    }
    alert(r);
}
calculate();
</script>
</head>
<body>
</body>
</html>

以上方式很容易造成浏览器卡死或内存溢出

2.由于HTML5的特性,我们可以很容易的使用web worker,就不会产生以上的问题了:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script type="text/javascript">
var worker = new Worker('test.js');
worker.onmessage = function (e) {
    alert('和:' + e.data);
};
function calculate() {
    var num = 1000000;
    worker.postMessage(num);
}
calculate();
</script>
</head>
<body>
</body>
</html>

传入Worker的文件内容为:

onmessage = function (e) {
    var num = e.data;
    var r = 0;
    for (var i = 1; i < num; i++) {
        r += i;
    }
    postMessage(r);
}

运行后,结果很快的弹出:

3.使用worker来实现一个比较复杂的计算,100内能被3整除的整数:与线程进行数据交互

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<style>
span
{
    padding: 10px;
}
</style>
<script src="../jquery-1.7.1.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
    var worker = new Worker('test1.js');
    worker.postMessage('');
    worker.onmessage = function (e) {
        var arr = e.data.split(';');
        for (var i = 0, len = arr.length; i < len; i++) {
            var dom = $('<span>' + arr[i] + '</span>');
            $('#body').append(dom);
        }
    }
});
</script>
</head>
<body>
<div id='body' style=' width: 400px; word-break:break-all; word-wrap:break-word; '>
</div>
</body>
</html>

test1.js的代码

<script type="text/javascript">
//生成数组的程序
onmessage = function (e) {
    var arr = [];
    for (var i = 0; i < 100; i++) {
        arr.push(parseInt(Math.random() * 100));
    }

    var worker = new Worker('test2.js');
    worker.postMessage(JSON.stringify(arr));
    worker.onmessage = function (e) {
        //把挑选结果发回前台
        postMessage(e.data);
    };
}
</script>

test2.js的代码

<script type="text/javascript">
//判断数组所有数据是否被3整除 
onmessage = function (e) {
    var arr = JSON.parse(e.data);
    var str = '';
    for (var i = 0, len = arr.length; i < len; i++) {
        if (parseInt(arr[i]) % 3 == 0) {
            if (str != '') str += ';';
            str += arr[i];
        }
    }
    postMessage(str);
    close();
};
</script>

程序生成的结果为:

程序逻辑描述:

这里用了个线程嵌套

首先执行前台程序,这里初始化了一个子线程“test1”用于将100个数组初始化

然后子线程test1又初始化了子线程test2(用于遍历数组,取出能被3整除的数字,组成字符串),test1将数组数据传给test2

test2 接收test1数据,计算后将将字符串转给test1,test1转给前台,前台执行自己的逻辑

流程结束

二、WebSocket protocol 是HTML5一种新的协议。

它实现了浏览器与服务器全双工通信(full-duple)。一开始的握手需要借助HTTP请求完成。原理参照:

https://www.zhihu.com/question/20215561

实例参照:

HTML5 WebSockets 基础使用教程

http://blog.csdn.net/charlene0824/article/details/51926463

Node.js + Web Socket 即时聊天程序:

http://www.cnblogs.com/Wayou/p/hichat_built_with_nodejs_socket.html

 

 

 

4 Comments

Leave a comment