javascript执行机制
在html5之前,浏览器中javascript的运行都是以单线程的方式工作的,虽然有多种方式实现了对多线程的模拟(例如:javascript 中的 tinterval 方法,ttimeout 方法等),但是在本质上程序的运行仍然是由 javascript 引擎以单线程调度的方式进行的。在 html5 中引入的工作线程使得浏览器端的 javascript 引擎可以并发地执行 javascript 代码,从而实现了对浏览器端多线程编程的良好支持。
javascript中的多线程 – webworker
html5 中的 web worker 可以分为两种不同线程类型,一个是专用线程 dedicated worker,一个是共享线程 shared worker。两种类型的线程各有不同的用途。
专用型web worker
专用型worker与创建它的脚本连接在一起,它可以与其他的worker或是浏览器组件通信,但是他不能与dom通信。专用的含义,我想就是这个线程一次只处理一个需求。专用线程在除了ie外的各种主流浏览器中都实现了,可以放心使用。
创建线程
创建worker很简单,只要把需要在线程中执行的javascript文件的文件名传给构造函数就可以了。
线程通信
在主线程与子线程间进行通信,使用的是线程对象的postmessage和onmessage方法。不管是谁向谁发数据,发送发使用的都是postmessage方法,接收方都是使用onmessage方法接收数据。postmessage只有一个参数,那就是传递的数据,onmessage也只有一个参数,假设为event,则通过event.data获取收到的数据。
发送json数据
json是js原生支持的东西,不用白不用,复杂的数据就用json传送吧。例如:
复制代码 代码如下:
postmessage({‘cmd’: ‘init’, ‘timestamp’: date.now()});
处理错误
当线程发生错误的时候,它的onerror事件回调会被调用。我的作文所以处理错误的方式很简单,就是挂接线程实例的onerror事件。这个回调函数有一个参数error,这个参数有3个字段:message – 错误消息;filename – 发生错误的脚本文件;lineno – 发生错误的行。
销毁线程
在线程内部,使用clo方法线程自己销毁自己。在线程外部的主线程中,使用线程实例的terminate方法销毁线程。
下面从一个例子看线程的基本操作:
html代码:
复制代码 代码如下:
<!doctype html>
<html>
<head>
<meta http-equiv=”content-type” content=”text/html; chart=utf-8″ />
<title>web worker fibonacci</title>
<script type=”text/javascript”>
onload = function(){
var worker = new worker(‘fibonacci.js’);
worker.onmessage = function(event) {
console.log(“result:” + event.data);
};
worker.onerror = function(error) {
console.log(“error:” + error.message);
};
worker.postmessage(40);
}
</script>
</head>
<body>
</body>
</html>
脚本文件fibonacci.js代码:
复制代码 代码如下:
//fibonacci.js
var fibonacci = function(n) {
return n < 2 ? n : arguments.callee(n – 1) + arguments.callee(n – 2);
};
onmessage = function(event) {
var n = parint(event.data, 10);
postmessage(fibonacci(n));
};
把它们放到相同的目录,运行页面文件,查看控制台,可以看到运行的结果。
这里还有一点,在主线程中,onmessage事件可以使用另外一种方式挂接:
复制代码 代码如下:
worker.addeventlistener(‘message’, function(event) {
console.log(“result:” + event.data);
}, fal);
个人觉得很麻烦,不如用onmessage直接。
使用其他脚本文件
工作线程可以使用全局方法importscripts来加载和使用其他的域内脚本文件或者类库。例如下面都是合法的使用方式:
复制代码 代码如下:
importscripts();/* imports nothing */
importscripts(‘foo.js’); /* imports just “foo.js” */
importscripts(‘foo.js’, ‘bar.js’);/* imports two scripts */
导入以后,可以直接使用这些文件中的方法。看一个网上的小例子:
复制代码 代码如下:
/**
* 使用 importscripts 方法引入外部资源脚本,在这里我们使用了数学公式计算工具库 math_utilities.js
* 当 javascript 引擎对这个资源文件加载完毕后,继续执行下面的代码。同时,下面的的代码可以访问和调用
* 在资源文件中定义的变量和方法。
**/
importscripts(‘math_utilities.js’);
onmessage = function (event)
{
var first = event.data.first;
var cond = event.data.cond;
calculate(first,cond);
};
function calculate(first,cond) {
//do the calculation work
var common_divisor=divisor(first,cond);
var common_multiple=multiple(first,cond);
postmessage(“work done! ” +
“the leasfeel名词t common multiple is ” + common_divisor +
” and the gre星空下的记忆atest common divisor is “+common_multiple);
}
网上也有网友想到了利用这里的importscripts方法解决资源预加载的问题(浏览器预先加载资源,而不会对资源进行解析和执行),道理也很简单。
线程嵌套
在工作线程中还可以在创建子线程,各种操作还是一样的。
同步问题
worker没有锁的机制,多线程的同步问题只能靠代码来解决(比如定义信号变量)。
共享型sharedwebworker
共享型web worker主要适用于多连接并发的问题。因为要处理多连接,所以它的api与专用型worker稍微有点区别。除了这一点,共享型web worker和专用型worker一样,不能访问dom,并且对窗体属性的访问也受到限制。共享型web worker也不能跨越通信。
页面脚本可以与共享型web worker通信,然而,与专用型web worker(使用了一个隐式的端口通信)稍微有点不同的是,通信是显式的通过使用一个端口(port)对象并附加上一个消息事件处理程序来进行的。
在收到web worker脚本的首个消息之后,共享型web worker把一个事件处理程序附加到激活的端口上。一般情况下,处理程序会运行自己的postmessage()方法来把一个消息返回给调用代码,接着端口的start()方法生成一个有效的消息进程。
看网上能找到的的唯一个例子:创建一个共享线程用于接收从不同连接发送过来的指令,然后实现自己的指令处理逻辑,指令处理完成后将结果返回到各个不同的连接用户。
html代码:
复制代码 代码如下:
<!doctype html>
<html>
<head>
<meta chart=”utf-8″>
<title>shared worker example: how to u shared worker in html5</title>
<script>
var worker = new sharedworker(‘个性签名sharedworker.js’);
var log = document.getelementbyid(‘respon_from_worker’);
worker.port.addeventlistener(‘message’, function(e) {
//log the respon data in web page
log.textcontent =e.data;
}, fal);
worker.port.start();
worker.port.postmessage(‘ping from ur web page..’);
//following method will nd ur input to sharedworker
function postmessagetosharedworker(input)
{
//define a json object to construct the request
var instructions={instruction:input.value};
worker.port.postmessage(instructions);
}
</script>
</head>
<body onload=”>
<output id=’respon_from_worker’>
shared worker example: how to u shared worker in html5
</output>
nd instructions to shared worker:
<input type=”text” autofocus oninput=”postmessagetosharedworker(this);return fal;”>
</input>
</body>
</html>
脚本文件代码:
复制代码 代码如下:
// 创建一个共享线程用于接收从不同连接发送过来的指令,指令处理完成后将结果返回到各个不同的连接用户。
var connect_number = 0;
onconnect = function(e) {
connect_number =connect_number+ 1;
//get the first port here
var port = e.ports[0];
port.postmessage(‘a new connection! the current connection number is ‘
+ connect_number);
port.onmessage = function(e) {
//get instructions from requester
var instruction=e.data.instruction;
var results=execute_instruction(instruction);
port.postmessage(‘request: ‘+instruction+’ respon ‘+results
+’ from shared worker…’);
};
};
/*
* this function will be ud to execute the instructions nd from requester
* @param instruction
* @return
*/
function execute_instruction(instruction)
{
var result_value;
//implement your logic here
//execute the instruction…
return result_value;
}
在上面的共享线程例子中,在主页面即各个用户连接页面构造出一个共享线程对象,然后定义了一个方法 postmessagetosharedworker 向共享线程发送来之用户的指令。同时,在共享线程的实现代码片段中定义 connect_number 用来记录连接到这个共享线程的总数。之后,用 onconnect 事件处理器接受来自不同用户的连接,解析它们传递过来的指令。最后,定义一个了方法 execute_instruction 用于执行用户的指令,指令执行完成后将结果返回给各个用户。
这里我们并没有跟前面的例子一样使用到了工作线程的 onmessage 事件处理器,而是使用了另外一种方式 addeventlistener。实际上,前面已经说过,这两种的实现原理基本一致,只是在这里有些稍微的差别,如果使用到了 addeventlistener 来接受来自共享线程的消息,那么就要先使用 worker.port.start() 方法来启动这个端口。之后就可以像工作线程的使用方式一样正常的接收和发送消息。
最后陈述
线程中能做的事:
1.能使用ttimeout(), cleartimeout(), tinterval(),clearinterval()等函数。
2.能使用navigator对象。
3.能使用xmlhttprequest来发送请求。
4.可以在线程中使用web storage。
5.线程中可以用lf获取本线程的作用域。
线程中不能做的事:
1.线程中是不能使用除na工艺美院vigator外的dom/bom对象,例如window,document(想要操作的话只能发送消息给worker创建者,通过回调函数操作)。
2.线程中不能使用主线程中的变量和函数。
3.线程中不能使用有”挂起”效果的操作命令,例如alert等。
4.线程中不能跨域加载js。
线程也是需要消耗资源的,而且使用线程也会带来一定的复杂性,所以如果没有充足的理由来使用额外的线程的话,那么就不要用它。
实用参考
官方文档:
webworker分类说明:
www.887551.com:
webworker概述:https://developer.mozilla.org/en/using_web_workers
本文发布于:2023-04-03 06:07:05,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/d51255d813e698063c260018d6acd222.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:突袭HTML5之Javascript API扩展1—Web Worker异步执行及相关概述.doc
本文 PDF 下载地址:突袭HTML5之Javascript API扩展1—Web Worker异步执行及相关概述.pdf
留言与评论(共有 0 条评论) |