前端黑魔法:webworker动态化,无需JS文件创建worker
前言

作者初始代码地址
(进入项目页面,里面的original-version目录下就是作者的最初的代码)

通过JS文件和路径创建webworker带来的问题
var worker =new Worker('work.js’)
四次转换,将一个普通函数强行变成WebWorker
但是 @simon3000 的建议让我眼前一亮!他告诉我,根据他使用webworker-loader(webpack技术栈)的经验,有一种连续转换的方式可以直接将一个普通函数变成WebWorker

// 文件名为main.js
function work () {
onmessage = ({data: {message}}) => {
console.log ('i am worker, receive:' + message);
postMessage ({result: 'message from worker'});
};
} const runWorker = f => {
const worker = new Worker (
URL.createObjectURL (new Blob ([`(${f.toString ()})()`]))
); worker.onmessage = ({data: {result}}) => {
console.log ('i am main thread, receive:' + result);
}; worker.postMessage ({message: 'message from main thread'});
}; const testWorker = runWorker (work);

用Promise和闭包的方式去改造
// 文件名为index.js
function work () {
onmessage = ({data: {jobId, message}}) => {
console.log ('i am worker, receive:-----' + message);
postMessage ({jobId, result: 'message from worker'});
};
} const makeWorker = f => {
let pendingJobs = {}; const worker = new Worker (
URL.createObjectURL (new Blob ([`(${f.toString ()})()`]))
); worker.onmessage = ({data: {result, jobId}}) => {
// 调用resolve,改变Promise状态
pendingJobs[jobId] (result);
// 删掉,防止key冲突
delete pendingJobs[jobId];
}; return (...message) =>
new Promise (resolve => {
const jobId = String (Math.random ());
pendingJobs[jobId] = resolve;
worker.postMessage ({jobId, message});
});
}; const testWorker = makeWorker (work); testWorker ('message from main thread').then (message => {
console.log ('i am main thread, i receive:-----' + message);
});

总结
- 第一,function.toString得到的并不是一个没有意义的字符串,它是完全可以被用来运行的
- 第二,通过这种方式,webworker不需要借助额外的JS文件了,webworker完全动态化和自由化,你可以在主线程中创建任意个webworker!
- 第三,我通过这次的交谈了解到一个道理,编程除了考量逻辑思维,信息差也是考量的一大因素。我之前也想过用webworker做这些事情,可是我不知道能用这样的四重转换呀!我也不知道function.toString得到的字符串居然是有作用的。信息差,也是会造成差距的。所以工程上也经验和前瞻也同样重要。
其他参考资料
- worker-loader源码: https://github.com/webpack-contrib/worker-loader
前端黑魔法:webworker动态化,无需JS文件创建worker的更多相关文章
- 前端开发面试题收集 JS
前端开发面试题收集-JS篇 收集经典的前端开发面试题 setTimeout的时间定义为0有什么用? javascript引擎是单线程处理任务的,它把任务放在队列中,不会同步执行,必须在完成一个任务后才 ...
- 前端迷思与React.js
前端迷思与React.js 前端技术这几年蓬勃发展, 这是当时某几个项目需要做前端技术选型时, 相关资料整理, 部分评论引用自社区. 开始吧: 目前, Web 开发技术框架选型为两种的占 80% .这 ...
- 【前端芝士树】Vue.js面试题整理 / 知识点梳理
[前端芝士树] Vue.js 面试题整理 MVVM是什么? MVVM 是 Model-View-ViewModel 的缩写. Model代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑. ...
- 前端开发之走进Vue.js
Vue.js作为目前最热门最具前景的前端框架之一,其提供了一种帮助我们快速构建并开发前端项目的新的思维模式.本文旨在帮助大家认识Vue.js,了解Vue.js的开发流程,并进一步理解如何通过Vue.j ...
- 前端开发必须知道的JS(二) 闭包及应用
http://www.cnblogs.com/ljchow/archive/2010/07/06/1768749.html 在前端开发必须知道的JS(一) 原型和继承一文中说过下面写篇闭包,加之最近越 ...
- css-dialog样式实现弹框蒙层全屏无需JS计算高度兼容IE7
<!DOCTYPE html><html><head> <meta charset="UTF-8"> <title> ...
- 前端开发必须知道的JS之闭包及应用
本文讲的是函数闭包,不涉及对象闭包(如用with实现).如果你觉得我说的有偏差,欢迎拍砖,欢迎指教. 在前端开发必须知道的JS之原型和继承一文中说过下面写篇闭包,加之最近越来越发现需要加强我的闭包应用 ...
- 为什么43%前端开发者想学Vue.js
根据JavaScript 2017前端库状况调查 Vue.js是开发者最想学的前端库.我在这里说明一下我为什么认为这也是和你一起通过使用Vue构建一个简单的App应用程序的原因. 我最近曾与Evan ...
- 从cocos2d-html5中提取出来的,用做前端开发的框架——cc.js
从cocos2d-html5中提取出来的,用做前端开发的框架——cc.js /************************************************************* ...
随机推荐
- SAP无法激活表问题
因为修改了表结构导致无法激活,刚开始以为是数据库没有调整,然后试着运行SE14,发现还是报错 这个时候就要看看数据库服务器时候正常,输入事务码ST04,查看概览,发现磁盘已满 登录HANA Studi ...
- loging日志的使用
2.日志: 记住怎么使用就好了 自己定义日志开始 import logging logger = logging.getLogger() # 创建一个logger fh = logging.FileH ...
- Sqlserver 查询分组 记录
select b.* from (select a.*,row_number() over (partition by 列1 order by 列2 desc) rn from a) b ; --如需 ...
- [luogu4886] 快递员(点分治,树链剖分,lca)
dwq推的火题啊. 这题应该不算是点分治,但是用的点分治的思想. 每次找重心,算出每一对询问的答案找到答案最大值,考虑移动答案点,使得最大值减小. 由于这些点一定不能在u的两颗不同的子树里,否则你怎么 ...
- 40 篇原创干货,带你进入 Spring Boot 殿堂!
两个月前,松哥总结过一次已经完成的 Spring Boot 教程,当时感受到了小伙伴们巨大的热情. 两个月过去了,松哥的 Spring Boot 教程又更新了不少,为了方便小伙伴们查找,这里再给大家做 ...
- Redis的常用命令与Java整合及高级应用篇
一,redis是什么? 首先数据库分为关系型数据库和非关系型数据库,关系型数据库是采用关系模型来组织数据的数据库,简单来说就是二维表格模型,同时保证事务的一致性. 相反非关系型数据库采用key ...
- 交叉编译QT 5.6.2 Shell脚本
测试环境: CPU: AT91SAM9X35 Linux: Atmel提供的linux-at91-linux4sam_5.3 (Linux-4.1.0) 转载请注明: 凌云物网智科嵌入式实 ...
- 入门MySQL——用户与权限
前言: 前面几篇文章为大家介绍了各种SQL语法的使用,本篇文章将主要介绍MySQL用户及权限相关知识,如果你不是DBA的话可能平时用的不多,但是了解下也是好处多多. 1.创建用户 官方推荐创建语法为 ...
- linux常用命令示例汇总
1.ping -c 3 -i 0.1 -W 1 -t 3 100.100.242.181 -c发包数目,-c 3三个 -i,发包间隔,-i 0.1,每隔0.1秒发一个包 -W,发包超时时间,-W 1, ...
- HillCrest Sensor HAL
1. 抽象定义 Google为Sensor提供了统一的HAL接口,不同的硬件厂商需要根据该接口来实现并完成具体的硬件抽象层,Android中Sensor的HAL接口定义在:hardware/libha ...