JavaScript Worker 另类玩法

Web Workers API 的 Worker 接口代表一个可以轻松创建的后台任务,正常情况下,需要引用一个js脚本文件,那么有没有可能直接使用而不用"加载"JS脚本呢?

Worker 是什么

Web Workers API 

(https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API)的 Worker 接口代表一个可以轻松创建的后台任务,并可以将消息发送回其创建者。创建一个工作程序只要简单的调用Worker() 构造函数,并指定一个要在工作线程中运行的脚本。

兼容性

http://caniuse.mojijs.com/Home/Html/item/key/webworkers/index.html

Worker正常使用:

est.js 线程文件

addEventListener("message",function (e) {    console.log(e.data)
})//...

 html

  var woker = new Worker("test.js");
    woker.postMessage("test");

输出:

线程生成过程

那么中间的加载js过程与当前网络速度相关,如果不稳定可能会出现加载时间加长或加载失败。如果开启多个,那么会生成多个请求。

下图生成三个Worker,加载同个js。

假如要建立多少不同的线程处理,还需要建立多个不同的js,不能动态的处理线程。

var woker = new Worker("test1.js");
    woker.postMessage("test1");var woker = new Worker("test2.js");
    woker.postMessage("test2");var woker = new Worker("test3.js");
    woker.postMessage("test3");

那么能不能动态的处理线程呢? 不需要“加载”js文件,把脚本传到线程内执行? Worker 要加载js,那么可以虚拟一个文件给它吗?

Blob

Blob 对象表示一个不可变、原始数据的类文件对象。Blob 表示的不一定是JS原生格式的数据。File 接口基于Blob,继承了 blob 的功能并将其扩展使其支持用户系统上的文件。

第一步,把字符变成一个文件(Blob):

生成Blob:

window.BlobBuilder =  window.BlobBuilder ||    window.WebKitBlobBuilder ||    window.MozBlobBuilder ||    window.MSBlobBuilder;//兼容Blobvar createBlob = function(data,mimeType){    var blob;    try {
        blob = new Blob([data], {type: mimeType})
    }catch (e)
    {        if(e.name == "TypeError" &&  BlobBuilder )
        {            var bb = new BlobBuilder();            if (typeof  data == "string")
            {                var arr = data
            }else
            {                if (data instanceof ArrayBuffer)
                {
                    data = new DataView(data)
                }                var arr = data.buffer;
            }


            bb.append(arr)
            blob =bb.getBlob(mimeType)

        }

    }    return blob;
} 

 测试:

function test() {            console.log("test")
    }    console.log(test.toString())

 输出:

生成一个js的Blob文件:

 function test() {            console.log("test")
    }   var str = test.toString();    var blob = createBlob(str,"application/javascript");    console.log(blob)

把Blob变成一个可访问的地址:    (URL.createObjectURL 传送门)

function test() {            console.log("test")
    }   var str = test.toString();    var blob = createBlob(str,"application/javascript");    var jssrc = URL.createObjectURL(blob)    console.log(jssrc)

测试Worker加载 

   function test() {
        addEventListener("message",function (e) {            console.log(e.data)
        })
    }   var str = test.toString() + ";\n test();";    //";\n test();"; 执行test();
    var blob = createBlob(str,"application/javascript");    var jssrc = URL.createObjectURL(blob)    var woker = new Worker(jssrc);
    woker.postMessage("test");

生成的线程:

输出:

现在的流程:

使用Blob方式后:

加载时间大概10-22ms ,可以动态的创建不同的线程。

开启多个相同的线程可以使用同一个Blob。

实时运算:

根据Blob方式实现了一套实时运算的线程封装,直接使用函数运算:

        var i =0;        //run([参数],线程函数) 返回Promise
        TGMG.thread.Thread.run(["test",[]],function (value,data) {            //线程内
            console.log(value,data)           console.log("i=",i);            var str = ""
            for (var i=0;i<100000;i++)
            {
                str += "--"
            }            //返回数据
            result(str)            //关闭线程
            close()
        }).then(function (value) {            //主线程
            //接收返回参数
            console.log(value)
        })

 输出:

变量 i 是主线程的变量,所以在线程内是访问不到的,得到是undefined

方式2:

 function test(value) {            return value + value
        }        var thread=  new TGMG.thread.Thread(
                {                    run:function (a,b,c) {                        //线程内
                        console.log(a,b,c)
                        result(test(a),test(b))
                        result(test(c),test(a))                        //关闭线程
                        close()
                    },                    result:function (valueA,valueB)                    {                        console.log(valueA,valueB)
                    }
                    ,method:test.toString()
                })
        thread.start(1,2,3)

 生成的线程:

输出:

结束

使用Blob方式加载后,可以不再使用实体js脚本来开启了,减少了维护的成本。实时创建,实时运算。


作者:腾讯IEG事业群\创意设计部\多媒体开发组员工——林雨

原文发布于微信公众号 - 腾讯NEXT学位(NextDegree)

原文发表时间:2018-06-29

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏mini188

Openfire集群源码分析

如果用户量增加后为了解决吞吐量问题,需要引入集群,在openfire中提供了集群的支持,另外也实现了两个集群插件:hazelcast和clustering。为了...

2109
来自专栏文武兼修ing——机器学习与IC设计

流水线式p2p接口的分析与实现

P2P接口是一种双向握手接口,传输的前级和后级各提供一个数据有效信号valid和忙信号busy信号,只有当两个信号达成某种指定情况时,握手完成,数据传输完成,否...

812
来自专栏喔家ArchiSelf

消息队列在RTOS的应用

传说互联网应用有两大利器,一个是缓存,另一个就是消息队列。 一直相对消息队列做一下梳理,希望早日另有成文。 一叶知秋,实际上消息队列在嵌入式系统中同样有着广泛的...

883
来自专栏张善友的专栏

替换EnterPrise Library 4.0 缓存应用程序块的CacheManager

缓存是用来提高应用程序性能的常见技术,其实现方式是将常用数据从慢数据源复制到更快的数据源。对于数据驱动的应用程序来说,该技术通常需要将从数据库或 Web 服务检...

1807
来自专栏听雨堂

【7】AccessDB快速数据访问

阅读目录 C#和VB数据访问的比较 AccessDB的设计 数据库的连接 三种主要操作 错误输出及调试 小结 C#和VB数据访问的比较 C#中要进行...

18310
来自专栏跟着阿笨一起玩NET

Microsoft SyncToy 文件同步工具

SyncToy 是由 微软 推出的一款免费的文件夹同步工具。虽然名字中有一个 Toy,但是大家可千万不要误以为它的功能弱爆了。实际上,我感觉这款软件还真是摆脱了...

722
来自专栏数据之美

Python RPC 远程调用脚本之 RPyC 实践

最近有个监控需求,需要远程执行集群每个节点上的脚本,并获取脚本执行结果,为了安全起见不需要账号密码登陆节点主机,要求只需要调用远程脚本模块的方法就能实现。 总结...

3446
来自专栏Linux Python 加油站

什么是爬虫?python爬虫基本知识

把互联网比喻成一个蜘蛛网,那么Spider就是在网上爬来爬去的蜘蛛。 网络蜘蛛是通过网页的链接地址来寻找网页的。

1573
来自专栏用户2442861的专栏

使用 libevent 和 libev 提高网络应用性能——I/O模型演进变化史

http://blog.csdn.net/hguisu/article/details/38638183(牛逼100多名)

1051
来自专栏周明礼的专栏

一步一步带你搭建一个“摩登”的前端开发环境

最近几年也陆续推出了多种不同的js类型系统用于增强js的健壮性,其中像 typescript 就是其中的佼佼者。当然我今天要讲的并不是typescript,而是...

1.5K0

扫码关注云+社区