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事业群\创意设计部\多媒体开发组员工——林雨