前端黑魔法: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 /************************************************************* ...
随机推荐
- Java学习|String,StringBuffer,StringBuilder?
1 String (1) String的创建机理 由于String在Java世界中使用过于频繁,Java为了避免在一个系统中产生大量的String对象,引入了字符串常量池.其运行机制是:创建一个字 ...
- Tomcat中文乱码问题
新从官网下载的Tomcat7和Tomcat8,在运行的时候都会有乱码的问题,就此发现问题,我们就给它就地正法! 经过初步的分析,问题产生的大概原因是由于Tomcat的log日志模块不识别中文的问题, ...
- Go输入输出格式化Printf
package main import ( "fmt" "os" ) type point struct { x, y int } func main() { ...
- list 列表常用方法
append(self, p_object) 在列表末端追加一个新元素 insert(self, index, p_object) 在某个 ...
- 弹性布局(display:flex;)属性详解
Flexbox 是 flexible box 的简称(注:意思是“灵活的盒子容器”),是 CSS3 引入的新的布局模式.它决定了元素如何在页面上排列,使它们能在不同的屏幕尺寸和设备下可预测地展现出来. ...
- Linux查找命令对比(find、locate、whereis、which、type、grep)
//太长不看版find查找磁盘空间,相较于locate和whereis速度较慢.find和locate的查找单位为文件或者目录,locate其实是find -name的另一种写法.locate和whe ...
- pip3 Traceback (most recent call last)错误调试
百度找的答案不知道是否正确反正不适用于deepin,就手动调试了一下,结果修复了原理不清楚. 调试环境: OS:deepin 15.11 Python3-pip 错误提示: python@python ...
- 分布式任务调度框架 Azkaban —— Flow 2.0 的使用
一.Flow 2.0 简介 1.1 Flow 2.0 的产生 Azkaban 目前同时支持 Flow 1.0 和 Flow2.0 ,但是官方文档上更推荐使用 Flow 2.0,因为 Flow 1.0 ...
- coco标注信息与labelme标注信息的详解、相互转换及可视化
引言 在做实例分割或语义分割的时候,我们通常要用labelme进行标注,labelme标注的json文件与coco数据集已经标注好的json文件的格式和内容有差异.如果要用coco数据集的信息,就要对 ...
- Linux 下安装 mysql8
1.下载mysql wget https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-8.0.13-linux-glibc2.12-x86_64.tar 2. ...