Web Worker在WebKit中的实现机制
web worker 是执行在后台的 JavaScript,独立于其它脚本。不会影响页面的性能。这是HTML5的一个标准;实现上讲。浏览器为wokrer启动了新的线程,从而实现了异步操作的功能;
以下是woker的一个简单样例。在html页面中。以worker.js为源文件。创建了名为“worker”的Worker对象。通过worker.postMessage()接口向worker线程发送消息; worker线程将JSON格式化传递的两个数据相加后。再通过postMessage()接口将消息发送回页面js执行的主线程。 主线程再在onMessage()函数中处理woker线程发来的消息;
main.html
<html>
<head>
<script type="text/javascript">
var worker = new Worker('worker.js');
var obj = {"first":1, "second":2};
worker.postMessage(obj);
worker.onmessage = function (event) {
alert(event.data);
} function postMsg(){
if (worker)
worker.postMessaage(obj);
}
</script>
</head>
<body>
<button onclick="postMsg()">post</button>
</body>
</html>
worker.js
onmessage = function (event)
{
var data = event.data;
var first=data.first;
var second=data.second;
handleTask(first,second);
}; function handleTask(a, b)
{
var out = a + b;
postMessage("Worker Done! out = " + out);
}
WebKit载入并运行js的流程简单分成下面几步:
1. 运行到"var worker = new Worker('worker.js')“时。在内核中构造WebCore::JSWorker对象(JSBbindings层)以及相应的WebCore::Worker对象(WebCore模块);
2. 构造JSWorker对象的过程中,依据初始化的url地址"worker.js"发起异步载入的流程;
3. 运行worker.postMessage()。向worker线程发送JSON格式化的消息数据; 由于这个时候。worker线程还没有创建,所以消息数据放在一个暂时消息队列中;
4. worker.js异步载入完毕后,创建并启动worker线程。并将暂时消息队列中的消息数据copy到woker相应的WorkerRunLoop的消息队列中;
5. worker线程创建完毕后。開始处理WorkerRunLoop的消息队列中所保存的消息;
6. woker线程发送消息到主线程。
7. 主线程收到worker线程发送的消息,运行onMessage();
在经过一轮消息来回后,我们假设通过样例中button按钮来异步触发消息发送。那么步骤3的运行会有差别; 这个时候由于worker线程已经创建。所以消息会直接加入到WorkerRunLoop的消息队列中;
为了搞清楚整个实现机制,我们先来看一下WebKit内部worker相关的类。 当中Worker相应主页面JS中的'worker'对象(主线程中),而DedicatedWorkerThread表示worker线程; WorkerMessagingProxy关联了Worker对象与worker线程,从而实现主线程与worker线程之间的消息中转; DedicatedWorkerThread通过WorkerScriptController控制worker.js文件里的脚本在worker线程中的运行;浏览器会为worker线程创建一个独立的虚拟机环境(VM);
以下来看一下具体流程:
1. worker.js的异步载入步骤例如以下图,载入是在创建WebCore::JSWorker和WebCore::Worker对象的时候发起的。而且是异步载入的流程,不会堵塞兴许JS的运行,这也是为什么首次调用worker.postMessage()的时候。会出现worker线程还没有创建的情况;
2. worker线程的创建例如以下图所看到的。
能够看出。当worker.js载入完毕后。WebKit会通过中转对象WorkerMessagingProxy创建DedicatedWorkerThread对象,并启动WorkerThread; WorkerMessagingProxy保持DedicatedWorkerThread对象的指针;
3. 主线程向worker线程发送消息的流程例如以下。当js运行到"worker.postMessage()“时,终于会通过JS主线程虚拟机映射到JSWorker::postMessage()函数,并通过中转对象WorkerMessagingProxy将消息加入到worker的消息队列。 假设worker线程在发送消息的时候,还没有创建。我们看到有个m_queueEarlyTasks对象会暂时保存当前消息,并在worker线程创建后再转移到正式的消息队列中; 否则。直接将消息加入到WorkerRunLoop管理的正式消息队列中;
4. worker线程中处理消息的流程例如以下。这就是worker.js中開始运行”onmessage()”的流程; 我们能够看到DedicatedWorkThread对象在自己的线程环境下的runLoop取出消息队列中的数据运行。而运行是通过EventTarget::dispatchEvent()分发并fire一个"message"类型的事件来实现的;
.
5. 下图是在worker线程中发送消息的流程,也是通过WorkerMessagingProxy来进行中传。最后会触发Document::postTask()函数,该函数实际上将Document::didReceiveTask()函数抛到主线程上去运行。
6. 下图是main线程上处理消息的流程, Document::didReceiveTask()在主线程上開始运行。终于也是通过dispatch并fire一个"message"类型的事件实现消息的处理。
。
所以总得来讲。woker的机制是通过中转对象实现消息的传递,再通过"message"事件完毕消息的处理;
(转载请注明出处:http://blog.csdn.net/codigger)
Web Worker在WebKit中的实现机制的更多相关文章
- Web worker 与JS中异步编程的对比
0.从一道题说起 var t = true; setTimeout(function(){ t = false; }, 1000); while(t){ } alert('end'); 问,以上代码何 ...
- 【转向Javascript系列】深入理解Web Worker
本文首发在alloyteam团队博客,链接地址http://www.alloyteam.com/2015/11/deep-in-web-worker/ 上一篇文章<从setTimeout说事件循 ...
- 关于Web Worker你必须知道的7件事
介绍 通过使用Web Worker, 我们可以在浏览器后台运行Javascript, 而不占用浏览器自身线程.Web Worker可以提高应用的总体性能,并且提升用户体验.如果你想在自己的Web应用中 ...
- html5之web worker
Web Worker 在本文中 与 Web Worker 进行双向通信 WindowTimers 在 IE10 Platform Preview 4 中对 Web Worker 的更新 API 参 ...
- HTML5新增的一些属性和功能之八——web Worker
Web Workers 为什么用web workers? 浏览器的原理中决定了页面打开只有一个主线程--UI渲染线程,如果线程中有耗时的程序(js)会阻塞线程,使得页面中其他的UI无法渲染,我们一般把 ...
- H5中的web worker示例demo分析
web worker 是运行在后台的 JavaScript,不会影响页面的性能. 什么是 Web Worker? 当在 HTML 页面中执行脚本时,页面的状态是不可响应的,直到脚本已完成. web w ...
- vue中使用web worker
众所周知,JavaScript是单线程的,一些复杂比较耗时的操作,会阻塞页面的渲染交互,引起页面卡顿,影响用户体验.web worker是html5的新特性之一,主要就是用来解决此类问题,为页面额外开 ...
- HTML5中的Web Worker技术
为了让后台程序更好的执行,在HTML5中设计了Web Worker技术.Web Worker的产生主要是考虑到在HTML4中JavaScript Web程序都是以单线程的方式执行的,一旦前面的脚本花费 ...
- HTML5中的Web Worker
什么是 Web Worker? 当在 HTML 页面中执行脚本时,页面是不可响应的,直到脚本已完成. Web worker 是运行在后台的 JavaScript,独立于其他脚本,不会影响页面的性能.您 ...
随机推荐
- 谁说程序员都是苦逼的——看看兄弟连上海S2班的点点滴滴
时间过的很快,上海校区第三期马上临近开班,第一期的学员也结束了自己第一个项目. 今天,2013.05.08日,我亲自参加了S01的第一个项目答辩,也为你们记录下了这样那样的一些时刻.其 ...
- JavaScript + CSS3 实现的海报画廊特效
原文:JavaScript + CSS3 实现的海报画廊特效 这是慕课网上<CSS3+JS 实现超炫的散列画廊特效>的源代码,我修改了一些 bug 和调优了一些细节,并把学习过程中并不了解 ...
- 王立平--android中的anim(动画)
简单有用步骤: 1.新建anim目录. 2.在anim下新建xml文件, 3.在xml下编写自己须要动画. 简单样例: 给Imageview加入动画 public class MainActivity ...
- 按 Eclipse 开发喜好重新布置 cocos2dx 目录层次
[tonyfield 2013.08.29 ] 1. Cocos2dx 库的改动 处于个人的固执,花一天时间重新布置了cocos2dx 2.1.4的目录层次,将android平台无关的代码全数裁剪, ...
- HOJ 2245 浮游三角胞(数学啊 )
题目链接:http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=2245 Time Limi ...
- linux log系统图
log系统图 先贴图,怎么样,效果还不错吧,根据个人理解画的,如果不行将就用着吧. 解说 syslog是一种机制,在wiki中说这种机制可以使用udp,tcp,unix socket等把日志记录在 ...
- Memcahce(MC)系列(一)Memcache介绍、使用、存储、算法、优化
写在前面:前不久在工作中被问到关于MC一致哈希的问题,由于时隔太久差点儿忘记,特前来恶补一下MC,下面是前几年在工作中学习MC时的一些资料,来历不明,特整理一下,希望对大家的学习也能有帮助. 32 的 ...
- php编码
原文:php编码 PHP 页面编码声明与用header或meta实现PHP页面编码的区别 php的header来定义一个php页面为utf编码或GBK编码 php页面为utf编码 header ...
- Mybatis 3 返回布尔值,需要注意的地方
在Mybatis中,有时候需要返回布尔值 ,来确定某个记录行是否存在. 例如: <select id="isExistCode" parameterType="st ...
- linux c socket 案源
service结束 #include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #inclu ...