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 条评论
登录 后参与评论

相关文章

来自专栏大内老A

了解ASP.NET MVC几种ActionResult的本质:JavaScriptResult & JsonResult

在之前的两篇文章(《EmptyResult & ContentResult》和《FileResult》)我们剖析了EmptyResult、ContentResu...

1908
来自专栏互联网杂技

React一种少用的组件通信方式,但是简单

831
来自专栏前端小吉米

打造多线程 Web

853
来自专栏技术博客

Asp.Net Web API 2第八课——Web API 2中的属性路由

阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.h...

734
来自专栏晓晨的专栏

ASP.NET Core 中间件(Middleware)详解

1062
来自专栏技术博客

Asp.Net Web API 2第十二课——Media Formatters媒体格式化器

阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.h...

663
来自专栏极客慕白的成长之路

前端知识点总结 : Vue

作用:将表达式执行的结果 输出当调用元素的innerHTML中;还可以将数据绑定到视图。

341
来自专栏菩提树下的杨过

利用Spring MVC搭建REST Service

之前写过一篇 利用JAX-RS快速开发RESTful 服务 今天来看下spring-mvc框架如何实现类似的功能:  一、pom.xml 1 <?xml v...

18310
来自专栏Jackson0714

WCF传输1-你是否使用过压缩或Json序列化?

38610
来自专栏DOTNET

.Net多线程编程—误用点分析

1 共享变量问题 错误写法: 所有的任务可能会共享同一个变量,所以输出结果可能会一样。 1 public static void Error() 2 { 3 ...

3028

扫码关注云+社区