前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JavaScript Worker 另类玩法

JavaScript Worker 另类玩法

作者头像
腾讯NEXT学位
发布2018-07-02 11:23:09
8870
发布2018-07-02 11:23:09
举报
文章被收录于专栏:腾讯NEXT学位

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 线程文件

代码语言:javascript
复制
addEventListener("message",function (e) {    console.log(e.data)
})//...

 html

代码语言:javascript
复制
  var woker = new Worker("test.js");
    woker.postMessage("test");

输出:

线程生成过程

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

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

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

代码语言:javascript
复制
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:

代码语言:javascript
复制
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;
} 

 测试:

代码语言:javascript
复制
function test() {            console.log("test")
    }    console.log(test.toString())

 输出:

生成一个js的Blob文件:

代码语言:javascript
复制
 function test() {            console.log("test")
    }   var str = test.toString();    var blob = createBlob(str,"application/javascript");    console.log(blob)

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

代码语言:javascript
复制
function test() {            console.log("test")
    }   var str = test.toString();    var blob = createBlob(str,"application/javascript");    var jssrc = URL.createObjectURL(blob)    console.log(jssrc)

测试Worker加载 

代码语言:javascript
复制
   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方式实现了一套实时运算的线程封装,直接使用函数运算:

代码语言:javascript
复制
        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:

代码语言:javascript
复制
 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事业群\创意设计部\多媒体开发组员工——林雨

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-06-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 腾讯NEXT学位 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档