>>分享Web前端开发技术,并对孙卫琴的《精通Vue.js:Web前端开发技术详解》提供技术支持 书籍支持  卫琴直播  品书摘要  在线测试  资源下载  联系我们
发表一个新主题 开启一个新投票 回复文章 您是本文章第 16015 个阅读者 刷新本主题
 * 贴子主题:  js Worker 线程收集1~9999的之间所有质数;Worker线程交换数据;多个线程嵌套 回复文章 点赞(0)  收藏  
作者:mary    发表时间:2021-02-04 04:48:16     消息  查看  搜索  好友  邮件  复制  引用

  
在平时的运行的javascript脚本都在主线程中执行,如果当前脚本包含复杂的、耗时的代码。那么JavaScript脚本的执行将会被阻塞,甚至整个刘看齐都是提示失去响应。
例子:
  假设程序需要计算、收集1~9999的之间所有质数,不采用后台线程,而是之间是使用JavaScript前台线程的计算、收集质数。代码如下。    
<html>
<head>
    <meta name="author" content="Yeeku.H.Lee(CrazyIt.org)" />
    <meta http-equiv="Content-Type" content="text/html; charset=GBK" />
    <title> 计算质数 </title>
</head>
<body>
    <p>已经发现的所有质数:<div id="result"></div></p>
    <script type="text/javascript">
        var n = 1;
        search:
        while (n < 99999)
        {
            // 开始搜寻下一个质数
            n += 1;
            for (var i = 2; i <= Math.sqrt(n); i++)
            {
                // 如果除以n的余数为0,开始判断下一个数字。
                if (n % i == 0)
                {
                    continue search;
                }
            }
            document.getElementById('result').innerHTML += (n + ", ");
        }
    </script>
</body>
</html>

  浏览器久久未响应,一篇空白。最后过来七八秒全部崩出来。如果改为使用webWorker启用多线程呢?使用Worker创建贤臣非常简单,只要调用Worker的构造器就可以。    

<head>
    <title></title>
    <script>
        var worker = new Worker('worker12.js');
        worker.onmessage = function (event) {
            document.getElementById("result").innerHTML += event.data + ",";
        }

    </script>
</head>
<body>
    <p>
        已经发现的所有质数:<div id="result" style="width: 1500px; height:auto; border:1px solid red; word-wrap: break-word; ">
        </div>
    </p>
</body>
</html>

  Worker.js    

var n = 1;
search:
while (n < 10000) {
    // 开始搜寻下一个质数
    n += 1;
    for (var i = 2; i <= Math.sqrt(n); i++) {
        // 如果除以n的余数为0,开始判断下一个数字。
        if (n % i == 0) {
            continue search;
        }
    }
    // 发现质数
    postMessage(n);
}

  点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小
注意:
???Worker启动的子线程找到质数之后,并不能之间把找到的质数更新在页面上显示,必须通过postMessage(n)发送消息给前台JavaScript通信。
例子2:Worker线程交换数据:    

      <html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>多个线程交换数据</title>
    <script>
        var car = function () {
            var start = document.getElementById("start1").value;
            var end = document.getElementById("end1").value;

            if (start >= end) {
                return;

            } else {

                var cal = new Worker("Worker.js");
                // 定义需要提交给Worker线程的数据
                var data = {
                    start: start,
                    end: end
                };
                // 向Worker线程提交数据。
                cal.postMessage(JSON.stringify(data));
                cal.onmessage = function (event) {
                    document.getElementById("result").innerHTML += event.data + ",";
                }
            }
        }

    </script>
</head>
<body>
    起始值:<input type="text" id="start1" /><br />
    结束值:<input type="text" id="end1" /><br />
    <input type="button" value="点击" onclick="car();" />
    <div id="result" style="width: 1500px; height: auto; border: 1px solid red; word-wrap: break-word;">
    </div>
</body>
</html>

  worker.js    

onmessage = function (event) {
    // 将数据提取出来。
    var data = JSON.parse(event.data);
    // 取出start参数
    var start = data.start;
    // 取出end参数
    var end = data.end;
    var result = "";
    search:
    for (var n = start; n <= end; n++) {
        for (var i = 2; i <= Math.sqrt(n); i++) {
            // 如果除以n的余数为0,开始判断下一个数字。
            if (n % i == 0) {
                continue search;
            }
        }
        // 搜集找到的质数
        result += (n + ",");
    }
    // 发送消息,将会触发前台JavaScript脚本中
    // Worker对象的onmessage方法
    postMessage(result);
}

  点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小
例子3:多个线程嵌套    

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>多个线程嵌套 </title>
    <script>
        var car = function () {
            var start = document.getElementById("start1").value;
            var end = document.getElementById("end1").value;
            var count = document.getElementById("count1").value;

            var worker = new Worker('worker.js');
            var data = {
                start: start,
                end: end,
                count: count
            };
            worker.postMessage(JSON.stringify(data));
            worker.onmessage = function (event) {
                document.getElementById("result").innerHTML += event.data + ",";
            }

        }

    </script>
</head>
<body>
    起始值:<input type="text" id="start1" /><br />
    结束值:<input type="text" id="end1" /><br />
    个数:<input type="text" id="count1" /><br />
    <input type="button" value="点击" onclick="car();" />
    <div id="result" style="width: 1500px; height: auto; border: 1px solid red; word-wrap: break-word;">
    </div>
</body>
</html>

  worker.js    

onmessage = function (event) {
    // 将数据提取出来。
    var data = JSON.parse(event.data);
    // 取出start参数
    var start = data.start;
    // 取出end参数
    var end = data.end;
    // 取出count参数
    var count = data.count;
    var result = "";
    search:
    for (var n = start; n <= end; n++) {
        for (var i = 2; i <= Math.sqrt(n); i++) {
            // 如果除以n的余数为0,开始判断下一个数字。
            if (n % i == 0) {
                continue search;
            }
        }
        // 搜集找到的质数
        result += (n + ",");
    }
    // 再次启动Worker线程
    var sub = new Worker("subworker.js");
    // 把需要处理的数据传入启动的Worker线程中
    sub.postMessage({ result: result, count: count });
    sub.onmessage = function (event) {
        // 发送消息,将会触发前台JavaScript脚本中
        // Worker对象的onmessage方法
        postMessage(event.data);
    }

}

  subworker.js    

onmessage = function (event) {
    // 将数据提取出来。
    var data = event.data;
    // 提取所有质数
    var primeNums = data.result.split(",")
    var randResult = "";
    for (var i = 0; i < data.count; i++) {
        // 计算一个随机索引值
        var randIndex = Math.floor(Math.random()
            * (primeNums.length - 1));
        // 随机地"收集"一个质数
        randResult += (primeNums[randIndex] + ",");
    }
    // 发送消息,将会触发启动它的JavaScript脚本中
    // 对应Worker对象的onmessage方法
    postMessage(randResult);

}

  点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小



----------------------------
原文链接:https://blog.51cto.com/14648170/2501482
作者:孙翰

程序猿的技术大观园:www.javathinker.net



[这个贴子最后由 flybird 在 2021-02-14 19:01:35 重新编辑]
  Java面向对象编程-->Lambda表达式
  JavaWeb开发-->Web运作原理(Ⅳ)
  JSP与Hibernate开发-->域对象在持久化层的四种状态
  Java网络编程-->客户端协议处理框架
  精通Spring-->Vue Router路由管理器
  Vue3开发-->Vue组件开发基础
  10个 Web 开发人员的常用的 Chrome 扩展程序
  vue3 composition API的用法
  JavaScript实现睡眠函数
  js判断上传图片大小及尺寸
  Vue+Vant中van-list请求数据(数据请求调用公用方法)
  14个JavaScript优化建议
  jQuery 遍历DOM 树中的同胞元素
  HTML DOM Image图片对象
  JavaScript Array 对象
  CSS3 文本效果
  CSS 伪类
  HTML5 表单属性
  JavaScript 闭包
  JavaScript 对象 的创建和使用
  一文读懂前端技术演进:盘点Web前端20年的技术变迁史
  更多...
 IPIP: 已设置保密
楼主      
1页 0条记录 当前第1
发表一个新主题 开启一个新投票 回复文章


中文版权所有: JavaThinker技术网站 Copyright 2016-2026 沪ICP备16029593号-2
荟萃Java程序员智慧的结晶,分享交流Java前沿技术。  联系我们
如有技术文章涉及侵权,请与本站管理员联系。