首先,这是一篇不严谨的博文。

本文仅供参考,无法在实际生产中运用。

在捯饬文件分片上传的过程中,我总是觉得单线程太慢了。

于是想,用webWorker呗。

首先,我们可以查看一下WebWorker的兼容性。根据MDN文档来看,主流浏览器都兼容。

但有个问题,MDN表示WebWorker只支持到IE10.如果要兼容到ie8,势必要维护两份上传代码,怎么破???

发挥我们聪明才智的时候到了


好了,我们可以开始开脑洞了,

要声明的是,我们只是实现Worker这个假的构造函数。

首先,WebWorker在书写逻辑上是同步的,但其实加载Worker这个行为是异步的。

其次,WebWorker依赖事件与主线程进行沟通,中间经过的数据会被toString()。

再者,WebWorker的api比较简单,模拟起来也比较方便。


首先来看Worker的interface定义

[Constructor(USVString scriptURL, optional WorkerOptions options), Exposed=(Window,Worker)]
interface Worker : EventTarget {void terminate();void postMessage(any message, optional sequence<object> transfer = []);attribute EventHandler onmessage;attribute EventHandler onmessageerror;
};dictionary WorkerOptions {WorkerType type = "classic";RequestCredentials credentials = "omit"; // credentials is only used if type is "module"DOMString name = "";
};enum WorkerType { "classic", "module" };Worker includes AbstractWorker;

Worker接口继承了EventTarget,所以还能使用addEventListener removeEventListener这俩api

所以我们要实现一个假的Worker,需要实现以下内容:

  • 加载Worker脚本

    • 加载规则为同域名,从根目录开始寻找。
    • 暂不做blob生成,对本篇文章主题而言没有意义。
  • 实现以下内容

    • 实现onmessage
    • 实现onmessageerror (文章中暂不实现)
    • 实现close
    • 实现terminate (文章中暂不实现)
    • 实现addEventListener (文章中暂不实现)
    • 实现removeEventListener (文章中暂不实现)
    • 实现个假事件。

一步一步来


为了模拟Worker的同步书写方式

我们需要实现一个同步加载脚本的方法 (●゚ω゚●)

注:在现代浏览器里已经不赞成使用了

(function (root) {var cache = {};// debugwindow.__rc = cache;var module = {};module.exports = null;var config = {rootPath: ''};function hash(str) {var hash = 5381,i    = str.length;while(i) {hash = (hash * 33) ^ str.charCodeAt(--i);}/* JavaScript does bitwise operations (like XOR, above) on 32-bit signed* integers. Since we want the results to be always positive, convert the* signed int to an unsigned by doing an unsigned bitshift. */return hash >>> 0;}var defaultShimFunction = function (code, f) {if (f) {return f.replace('[[code]]', code);}return code;};root.require = function (scriptPath, shim) {var path = scriptPath;shim = shim || '';if (/^(\/|https?:\/\/)/.test(scriptPath) !== true) {path = config.rootPath + scriptPath;}if (/\.js$/.test(path) === false) {path += '/index.js';}var keyName = path + '?hash=' + hash(shim);if (cache[path]) {if (cache[keyName]) {return cache[keyName]}eval(defaultShimFunction(cache[path], shim));return cache[keyName] = module.exports;}var request = new XMLHttpRequest();request.open('GET', path, false);request.send(null);if (request.status === 200) {cache[path] = request.responseText;eval(defaultShimFunction(cache[path], shim));cache[keyName] = module.exports;}return cache[keyName];};root.require.config = function (opts) {for (var i in opts) {config[i] = opts[i]}};
}(window));

(๑´ㅂ`๑)上述代码不要在意,主要实现的功能其实就是特别智障的在浏览器里同步加载commonjs模块。。。

加了个垫片,方便操作

万事具备,只欠东风

来吧,直接上代码,worker-ployfill.js

window.__wbus = {_lis: {},on: function (evt, fn) {this._lis[evt] = fn;},off: function (evt) {if (!evt) {this._lis = {};return;}delete this._lis[evt];delete this._lis['close' + evt];},emit: function (evt, data) {this._lis[evt] && this._lis[evt](data);}
};function copy (a) {if (typeof a === 'object') {var c = JSON.stringify(a);return JSON.parse(c);}return a;
}function FakeEvent (data, id) {this.data = copy(data);this.type = 'message';this.id = id;
}var uuid = 1;var FakeWorker = function (p) {var self = this;self._id = uuid++;window.__wbus.on(self._id, function (data) {var Fe = new FakeEvent(data, self._id);self.onmessage && self.onmessage.call(Fe, Fe);});window.__wbus.on('close' + self._id, function (data) {self.terminates();});var path = location.protocol + '//' + location.host + '/' + p;var wf = require(path, 'module.exports = function () {\var self = {};\self.postMessage = function (data) {\window.__wbus.emit(' + self._id + ', data);\};\self.onmessage = function () {};\self.close = function () { window.__wbus.emit(close' + self._id + ') };\[[code]]\;return self;\}\');this.worker = wf();
};FakeWorker.prototype.onmessage = function () {
};FakeWorker.prototype.postMessage = function (data) {if (!this.worker) {throw new ReferenceError('Worker already stoped!');}var d = new FakeEvent(data, this._id);this.worker.onmessage && this.worker.onmessage.call(d, d);
};FakeWorker.prototype.terminates = function () {this.worker = null;window.__wbus.off(this._id);
};module.exports = FakeWorker;

智障儿童欢乐多。

来,让我们玩一把吧,下面是测试代码。

<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>测试23333</title>
</head>
<body><span>{{text}}</span><script type="text/javascript" src="/static/js/require.js"></script><script type="text/javascript">require.config({rootPath: '/node_modules/'});</script><script type="text/javascript">var Worker = require('/static/js/worker-ployfill.js');var cpus = require('cpus/browser.js')().length;var workers = [];for (var i = 0; i < cpus; i ++) {workers[i] = new Worker('static/js/worker-test.js');}workers.forEach((item) => {item.onmessage = function (e) {console.log('main thread'),console.log('thread id: %s', e.id);console.log('msg: %s', JSON.stringify(e.data));};item.postMessage({message: 'message from main'});})</script>
</body>
</html>
// worker-test.js
self.onmessage = function (e) {console.log('worker thread'),console.log('thread id: %s', e.id);console.log('msg: %s', JSON.stringify(e.data));self.postMessage({message: 'from FackWorker'});
};

你看,智障系列

233333333.

搞笑向, 面向IE8的webworker-ployfill相关推荐

  1. Swift41/90Days - 面向轨道编程 - Swift 中的异常处理

    问题 在开发过程中,异常处理算是比较常见的问题了. 举一个比较常见的例子:用户修改注册的邮箱,大概分为以下几个步骤: 接收到一个用户的请求:我要修改邮箱地址 验证一下请求是否合法,将请求进行格式转化 ...

  2. 支付宝小程序面向个人开发者公测

    web前端教程 用大白话,来讲编程 昨日,支付宝小程序正式面向个人开发者开放公测,有开发能力的个人用户可访问支付宝小程序平台,扫码验证个人身份以后即可开始支付宝小程序账号申请并进行代码开发. 个人主体 ...

  3. 把你的项目升级到IE8

    简介 在前面的几篇文章中,我们介绍了IE8的一些非常酷和有用的新特性,在本文主要是介绍,在把自己的项目迁移到IE8时候的一些考虑.在介绍本文的内容时,将场景分析与技术选择等结合起来,分析在当前场景中如 ...

  4. IE8 beta2现已正式发布!

    l Internet Explorer 8 Beta 2于8月27日已经面向全球发布,共发布英文.德文.简体中文.日文四种语言版本; l http://www.ieaddons.com 也于同日启用, ...

  5. 面向接口编程VS《倚天屠龙记》里张三丰教无忌打太极

    搞笑哈,只细想想,编程和太极怎么能联系在一起了,是八秆子也打不着的哈! 昨天看了一篇文章是关于面向接口编程的文章,颇有心得,其实在今天中国IT软件行业的盛行,程序员们突飞猛涨,真正算的上程序员的又有几 ...

  6. css参考手册css3手册_CSS手册:面向开发人员CSS便捷指南

    css参考手册css3手册 I wrote this article to help you quickly learn CSS and get familiar with the advanced ...

  7. 面向95后的营销和增长,你需要知道这些( ゜- ゜)つロ 乾杯

    增长黑盒备用号,欢迎关注~ 大号出现了一些小意外被屏蔽,感谢各位朋友关心~ 为了以防万一,我们新建了两个公众号,一个是[增长社区],另一个是本号[增长黑盒Growthbox]备用,欢迎大家关注! 虽然 ...

  8. 企业IT管理员IE11升级指南【8】—— Win7 IE8和Win7 IE11对比

    企业IT管理员IE11升级指南 系列: [1]-- Internet Explorer 11增强保护模式 (EPM) 介绍 [2]-- Internet Explorer 11 对Adobe Flas ...

  9. 雏凤清音——面向数据的前端编程方法

    1 名词解释 桐花万里丹山路,雏凤清于老凤声--唐·李商隐<韩冬郎既席为诗相送因成二绝> 作为一种有别传统的前端编程方法,雏风名之. 面向数据的编程方法,避开繁琐的ui代码,直接针对前端数 ...

最新文章

  1. “数学不好,干啥都不行!”骨灰级程序员:其实你们都是瞎努力
  2. 卸载idea2020不干净_强制卸载软件程序、以及清理注册表
  3. 研诺首款D类音频放大器延长便携应用中的电池寿命
  4. exls导入数据库 php_PHP Excel导入数据到MySQL数据库
  5. 电机驱动TB6612FNG全网断货,可替代方案来了,文末送模块!
  6. hideprocess in bcb
  7. 彻底搞懂 Scrapy 的中间件
  8. 移动端调起数字键盘的问题
  9. NetBeans 时事通讯(刊号 # 67 - Aug 04, 2009)
  10. Ubuntu16.04 安装有道词典
  11. 002.操作系统的选择
  12. Google拒绝因搜索不良信息被传唤
  13. struts2 result随笔
  14. AI PRO I 第4章
  15. mysql留存率除了存储过程_基于MySQL分析线上充值留存率
  16. C# Cron表达式解析 .net 项目文件
  17. 发布和订阅业务交易事件库(BTE事件及函数)
  18. bzoj5369loj6433 [Pkusc2018]最大前缀和
  19. 冶金、水泥、化工行业自动化通信产品介绍
  20. java安装不了为什么_为什么java安装不了?

热门文章

  1. Linux高可用性方案之Heartbeat的CRM节点得分计算(原创)
  2. 进行SEPM的灾难恢复时导入数据库后,Symantec Endpoint Protection Manager(SEPM)无法登陆...
  3. 关于mysql存储大数据的问题
  4. 关于apache虚拟主机htttpd的配置实例 (更新中)
  5. jdbc excute方法理解的误区
  6. 铁钉的blog地址 http://nails.blog.51cto.com
  7. Python 经典模块可能都学过,10道题测试你会不会用?
  8. 手机没电了 鸿蒙还有用吗,记住这几个技巧,手机没电时可以有效延长使用时间...
  9. druid不能close mysql连接_alibaba druid mysql连接问题
  10. ApplicationContext应用上下文获取方式