上篇文章讲了 WebWorker 的简单用法,其实网上很多类似的文章,我写的也比较垃圾。不会的建议可以网上看比较好点的资料。

这里我会先讲下我的大致思路。然后会贴上一堆不实用的垃圾代码供参考。

WebWorker 中必然是无法访问 DOM 的,更无法创建 DOM 元素。如果想要实现把 Worker 中的东西渲染出来,只能把相关数据什么的放到主线程去渲染。这用消息机制是可以实现的。

DOM 既然只能在主线程渲染,那么事件 Worker 线程自然也是无能为力了。而更关键的是 Worker 和主线程通信的时候不能传递函数作为参数(toString 这种方式不作数),而事件处理程序都是函数。那么就只好通过一个标识来代替函数,在 Worker 里通过这个标识来决定具体执行什么操作。

Worker 和主线程的分工相对是明确的,完善后的代码也基本上不怎么会去写执行在主线程上代码的,主要还是去写执行在 Worker 里面的代码。而等下次要讨论的是如何把 HTML 编译成类似在下边的 worker.js 代码的 render 函数中直接用 JSON 写的那部分。

再之后要讨论 VDOM 相关的算法,到时候不管写的多烂,能用就行。

之后的之后就讨论一些动画,事件防抖等的处理方式,要放到很久之后才讨论了,还有很多没想好应该什么时候讨论的事情,一步步来吧,想到哪里就写到哪里,我一个纯高技术的,还是乱七八糟都学的人确实写不出多好的东西来,多练习下也许N年后就好些了吧。

这里直接不涉及任何 VDOM 相关的东西。所有的东西都是用 JSON 来表示而已。也说过以后的文章才会讨论 VDOM,我对 VDOM 也是一知半解。搞出的东西不会有多么高的保障。自己懂得的还是自己去研究的好,但好在这些算法开源的实现很多。学习后换成好点的就行了。

HTML 里面没有什么东西:

 <div id="root"></div>
<script src="main.js"></script>

在主线程中运行的 main.js 中主要是为了渲染 DOM,绑定事件。这里的代码远远不足以满足正常使用,但这里只是为了讲一部分想法,没必要写那么复杂。能够渲染 DOM,绑定个事件就行了。至于更多的需求以后慢慢再讨论。这里声明,这些代码完全不足以在项目中使用,不要拿着乱用,不然里面很多问题你会很难解决的。

 var worker = new Worker('worker.js');

 worker.addEventListener('message', function (event) {
console.log(event.data);
var message = event.data; switch (message.type) {
case 'render':
render(message.payload);
break;
}
}); function render(data) {
var root = document.getElementById('root'); root.innerHTML = ''; root.appendChild(createElement(data));
} function setAttrs(element, attrs) {
if (attrs) {
for (var name in attrs) {
element.setAttribute(name, attrs[name]);
}
}
} function setProps(element, props) {
if (props) {
for (var name in props) {
element[name] = props[name];
}
}
} function setEvents(element, events) {
if (events) {
for (var name in events) {
attachEvent(element, name, events[name]);
}
}
} function setChildren(element, children) {
if (children && children instanceof Array) {
children.forEach(function (item) {
element.appendChild(createElement(item));
});
}
} function createElement(data) {
if (!data) {
return null;
} var element = document.createElement(data.type); setAttrs(element, data.attrs);
setProps(element, data.props);
setEvents(element, data.events);
setChildren(element, data.children); return element;
} var eventBinders = {
onTap: {
bind: function (element, name, value) {
element.addEventListener('click', function () {
worker.postMessage({
type: 'command',
payload: {
name: value
}
});
});
}
}
}; function attachEvent(element, name, value) {
eventBinders[name].bind(element, name, value);
} function createAttribute(element, name, value) {
element.setAttribute(name, value);
}

在 Worker 线程中中执行的 worker.js 会处理很多事务。基本上逻辑什么的都在里面了。

 var data = {
value: 1
}; function onDecreaseClick() {
data.value -= 1;
render(data);
} function onIncreaseClick() {
data.value += 1;
render(data);
} function handleCommand(data) {
switch (data.name) {
case 'onDecreaseClick':
onDecreaseClick(data);
break;
case 'onIncreaseClick':
onIncreaseClick(data);
break;
}
} function render(data) {
self.postMessage({
type: 'render',
payload: {
type: 'div',
attrs: {},
props: {},
children: [
{
type: 'button',
events: {
onTap: 'onDecreaseClick',
},
props: {
textContent: 'Decrease'
}
},
{
type: 'span',
props: {
textContent: data.value
}
},
{
type: 'button',
events: {
onTap: 'onIncreaseClick',
},
props: {
textContent: 'Increase'
}
}
]
}
});
}
self.addEventListener('message', function (event) {
var message = event.data; switch (message.type) {
case 'command':
handleCommand(message.payload);
break;
}
});
render(data);

代码都很简单粗暴。虽然确实可以跑起来。但是无论是 DOM 渲染 还是 Worker 中的处理都是很简单的,同时也是不可实际生产使用的。接下来讨论过 VDOM 之后会进一步完善。

这次的东西写是写完了,但不知道是不是只有我自己能看懂自己写的啥。就当练手把。有空把整个项目的实现都写一遍,复习下也行,感觉不仅文笔差,思路好像也不是很好吧。

WebWorker 中将已处理好的 VDOM 数据提交主线程渲染 DOM的更多相关文章

  1. vue嵌套数据多层级里面的数据不自动更新渲染dom

    可以尝试手动调用更新 主要代码: vm.$forceUpdate() 官网

  2. idea中将已有项目转变为git项目,并提交到git服务器上

    idea中将已有项目转变为git项目,并提交到git服务器上 前言 有时候,本地有个项目不错,想要分享到github或者码云上,我们就会有这样的需求:项目在本地已经存在(可能不是git项目),又想提交 ...

  3. 四种常见的 POST-------- content-type数据提交方式

    HTTP/1.1 协议规定的 HTTP 请求方法有 OPTIONS.GET.HEAD.POST.PUT.DELETE.TRACE.CONNECT 这几种.其中 POST 一般用来向服务端提交数据,本文 ...

  4. Python_线程、线程效率测试、数据隔离测试、主线程和子线程

    0.进程中的概念 三状态:就绪.运行.阻塞 就绪(Ready):当进程已分配到除CPU以外的所有必要资源,只要获得处理机便可立即执行,这时的进程状态成为就绪状态. 执行/运行(Running)状态:当 ...

  5. HTTP POST请求数据提交格式(转)

    FROM: http://bbs.125.la/thread-13743350-1-1.html HTTP/1.1 协议规定的 HTTP 请求方法有 OPTIONS.GET.HEAD.POST.PUT ...

  6. [Android]使用AdapterTypeRender对不同类型的item数据到UI的渲染

    以下内容为原创,转载请注明: 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/3992843.html 本文讲的工具均放在AndroidBucket开源 ...

  7. 使用AdapterTypeRender对不同类型的item数据到UI的渲染

    要实现聊天功能中的发送不同类型的信息,比如纯文本.图片.语音.图文混排多媒体的数据等(具体效果看微信). 这里使用AdapterTypeRender在BaseTypeAdapter(这个之后会讲到)中 ...

  8. ligerui_实际项目_003:form中添加数据,表格(grid)里面显示,最后将表格(grid)里的数据提交到servlet

    实现效果: "Form"中填写数据,向本页"Grid"中添加数据,转换成Json数据提交,计算总和,Grid文本框可编辑,排序 图片效果: 总结: //disp ...

  9. jsp 页面json数据提交到后台spring处理举例

    0 前台: 'type'        : 'post', 'contentType' : 'application/json;charset=UTF-8', 'data'        : JSON ...

随机推荐

  1. Spring+Redis的部署与Redis缓存使用示例

    由于项目的业务需要,这两天折腾了一下Spring-redis配置,有了前面用Spring托管hibernate的经验,这次可以说是顺风顺水,大概说一下流程. ubuntu 安装 redis sudo ...

  2. 微信授权、获取用户openid-纯前端实现——jsonp跨域访问返回json数据会报错的纯前端解决办法

    近来,倒霉的后台跟我说让我拿个openid做微信支付使用,寻思很简单,开始干活. 首先引导用户打开如下链接,只需要将appid修改为自己的就可以,redirect_url写你的重定向url https ...

  3. PAT1012:The Best Rank

    1012. The Best Rank (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue To eval ...

  4. Docker的安装和测试

    1,Docker安装 Docker是啥,以及其与虚拟机的对比,就不介绍了,网上有很多资源可以学习和了解. 本篇文章重点介绍Docker的安装和测试使用. Docker的安装,分为离线安装和在线安装两种 ...

  5. jndi通俗理解以及它的指令缺陷

    jndi(java naming directory interface),可以把JNDI看成一个全局的目录服务接口,实现了这个接口的类可以提供你想要的东西,不管这个东西是什么,只要注册到了目录中就可 ...

  6. Java NIO Buffer缓冲区

    原文链接:http://tutorials.jenkov.com/java-nio/buffers.html Java NIO Buffers用于和NIO Channel交互.正如你已经知道的,我们从 ...

  7. 【转】MySQL datetime数据类型设置当前时间为默认值

    转自http://blog.csdn.net/u014694759/article/details/30295285 方法一: MySQL目前不支持列的Default 为函数的形式,如达到你某列的默认 ...

  8. CKEditor、UBB编辑器的使用总结

    2018-04-08 22:07:16.188 ERROR 14728 --- [nio-8082-exec-8] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Se ...

  9. Ueditor 专题

    https://github.com/xwjie/SpringBootUeditor 提交表单提交表单设置按照部署编辑器的教程,完成编辑器加载 把容器放到form表单里面,设置好要提交的路径,如下面代 ...

  10. 关于ArrayList的5道面试题

    我以面试官的身份参加过很多Java的面试,以下是五个比较有技巧的问题,我发现有些初级到中级的Java研发人员在这些问题上没有完全弄明白,似懂非懂.所以我写了一篇相关的文章,帮助初级Java研发人员弄清 ...