您好!欢迎访问家园网-www.jy.wang!

家园网

Worker对象处理线程代码分析

网络 作者:本站 点击:

Worker对象处理线程代码分析

html代码

<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<script type="text/javascript">
// 创建执行运算的线程
var worker = new Worker("kwb.js");
//接收从线程中传出的计算结果
worker.onmessage = function(event) 
{
    //消息文本放置在data属性中,可以是任何JavaScript对象.
    alert("合计值为" + event.data + "。");
};
function kwb() 
{
    //获取文本框的值
    var num1 = parseInt(document.getElementById("num1").value);
    var num = parseInt(document.getElementById("num").value);
   //对2个文本框提交的值进行判断
   if(num<num1){        
       alert('提交的运算不符合要求');
       return false;
    }
    //将获取的文本框的值用@拼接成字符串
    var subs=num1+'@'+num;
    //将数值传给线程
    worker.postMessage(subs);
}
</script>
</head>
<body>
<h1>对给定2个数字之间所有数值的计算</h1>
<hr color="#FF0000"><br>
初始数值:<input type="text1" id="num1"><br><br>
终极数值:<input type="text" id="num"><br><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<button onclick="kwb()">计算</button>
</body>


kwb.js代码:

onmessage = function(event){
    var num = event.data;
    var intarray=num.split('@'); //返回字符串中数字分隔符为@
    var result = 0;
   for (var i = parseInt(intarray[0]); i <= intarray[1]; i++) { //执行求和运算
   result += i;
   }
    postMessage( result); //返回运算结果拼接成的字符串
}



以下是对该 JavaScript 代码的逐行讲解:

onmessage = function(event){

定义一个名为 onmessage 的函数,当接收到消息时会自动调用此函数。通常用于 Web Workers 中处理来自主线程的消息。event 参数包含了发送过来的数据。


    var num = event.data;

从 event 对象中提取 data 属性,这个属性包含了从主线程传递过来的数据,并将其赋值给变量 num


	var intarray=num.split('@'); //返回字符串中数字分隔符为@

将字符串 num 按照字符 '@' 进行分割,生成一个数组 intarray。例如,如果 num = "1@5",那么 intarray 就是 ["1", "5"]。注释说明了分隔符是 '@'


	var result = 0;

初始化一个变量 result 为 0,用于存储后续的求和结果。


   for (var i = parseInt(intarray[0]); i <= intarray[1]; i++) {	//执行求和运算

使用 for 循环从 intarray[0](第一个数字)开始,到 intarray[1](第二个数字)结束,逐步累加每个数字。parseInt() 将字符串转换为整数。注释说明这是在执行求和运算。


   result += i;
   }

在每次循环中,将当前数字 i 加到 result 上。循环结束后,result 包含了从第一个数到第二个数之间所有整数的总和。


	postMessage( result); //返回运算结果拼接成的字符串

通过 postMessage() 方法将最终的求和结果 result 发送回主线程。注意,虽然注释提到“返回运算结果拼接成的字符串”,但实际代码中只是发送了一个数值,而不是字符串。

该代码整体功能是:接收一个以 '@' 分隔的两个数字组成的字符串,计算这两个数字之间的所有整数之和,并将结果返回给调用者。


postMessage() 方法将最终的求和结果 result 发送回主线程,

那是不是发送的结果就是sum,就是event.data?


postMessage() 方法发送的是 result 变量的值,而不是 event.data

在代码中,event.data 是从主线程接收到的数据,通常是一个以 '@' 分隔的字符串,比如 "1@5"

而 result 是代码内部计算得到的求和结果,是 result += i 累加后的数值。

所以 postMessage(result) 发送的是计算结果,而不是原始的 event.data

简单来说:

  • event.data:接收的数据(如 "1@5")

  • result:计算后的结果(如 15,即 1+2+3+4+5 的和)

  • postMessage(result):发送的是计算结果,不是原始数据


那你看最后postMessage() 方法发送的

是 result 变量的值传到哪里去了?

传给谁了?

postMessage()方法发送的result变量值的传输流程如下:

  1. 发送方向‌:在Web Worker线程(kwb.js)中,postMessage(result)将计算结果发送到‌主线程‌(即您的HTML页面)

  2. 接收方‌:在HTML页面的主线程中,通过worker.onmessage事件监听器来接收这个结果

  3. 具体处理‌:接收到的数据存储在event.data属性中,然后通过alert弹窗显示出来

所以完整的数据流向是:
Web Worker中的result变量 → postMessage()发送 → 主线程的worker.onmessage接收 → event.data → alert显示

这样就实现了从后台线程向前台页面传递计算结果的通信机制。



就是说最终计算的和存储到了event.data里面去了?


是的,最终计算的和确实存储到了event.data里面。

当Web Worker线程中的postMessage(result)执行时,计算结果result会被发送回主线程。在主线程中,通过worker.onmessage事件监听器接收这个消息时,计算结果就存储在event.data属性中。

这样设计使得主线程能够接收到Web Worker计算完成后的结果,并可以对其进行进一步处理或显示。


两段代码中的event是同一个吗?

这两段代码中的event参数虽然名称相同,但代表的含义和作用场景是不同的。

在第一段代码中,onmessage = function(event)是Web Worker线程中的事件处理函数。这里的event对象包含了从主线程发送过来的消息数据,event.data属性包含了实际传递的数据内容。当主线程调用worker.postMessage()发送数据时,Web Worker会接收到这个event对象。

在第二段代码中,worker.onmessage = function(event)是主线程中的事件处理函数。这里的event对象包含了从Web Worker线程发送回来的消息数据,event.data属性包含了Web Worker通过postMessage()发送的计算结果。

虽然两个event变量都包含data属性,但它们分别属于不同的执行环境:第一个属于Web Worker线程环境,第二个属于主线程环境。它们是两个独立的事件对象,只是都使用了相同的命名约定。

因此,这两个event对象虽然结构相似,但作用于不同的通信方向:第一个是接收主线程消息,第二个是接收Worker线程消息。


那这2个event能改成别的吗,

或者一个设为event1,另一个叫event2,行吗?


是的,这两个event参数可以改成不同的名称,比如event1和event2。这样可以更清楚地区分它们的作用。


在第一段代码中,Web Worker线程中的事件处理函数可以改为:

onmessage = function(event1){
    var num = event1.data;
    var intarray = num.split('@');
    var result = 0;
    for (var i = parseInt(intarray[0]); i <= intarray[1]; i++) {
        result += i;
    }
    postMessage(result);
}


在第二段代码中,主线程中的事件处理函数可以改为:

worker.onmessage = function(event2) {
    alert("合计值为" + event2.data + "。");
};


这样修改后,两个event参数的名称不同,便于理解它们分别属于不同的执行环境和作用域。

// Web Worker线程中的事件处理函数
onmessage = function(event1){
    var num = event1.data;
    var intarray = num.split('@');
    var result = 0;
    for (var i = parseInt(intarray[0]); i <= intarray[1]; i++) {
        result += i;
    }
    postMessage(result);
}
// 主线程中的事件处理函数
worker.onmessage = function(event2) {
    alert("合计值为" + event2.data + "。");
};


代码说明:1. 该代码展示了如何将两个不同的event参数重命名为event1和event2
2. event1用于Web Worker线程接收主线程消息
3. event2用于主线程接收Web Worker线程返回的结果


如果改的话,函数块里面的也得对应改成和前面一样的,是吗


是的,如果将事件处理函数中的参数名从event改为其他名称,那么函数体内部所有使用该参数名的地方都必须相应修改。

例如,如果将第一个函数的参数名改为event1,那么函数体内所有使用event.data的地方都要改为event1.data。


// Web Worker线程中的事件处理函数
onmessage = function(event1){
    var num = event1.data;
    var intarray = num.split('@');
    var result = 0;
    for (var i = parseInt(intarray[0]); i <= intarray[1]; i++) {
        result += i;
    }
    postMessage(result);
}
// 主线程中的事件处理函数
worker.onmessage = function(event2) {
    alert("合计值为" + event2.data + "。");
};


代码说明:1. 该示例展示了如何将事件处理函数的参数名从event修改为其他名称
2. 修改后需要确保函数体内所有相关引用都同步更新
3. 这样做可以提高代码可读性,明确区分不同环境中的事件对象


worker.postMessage(subs);

这一句代码,最终数值传给谁了?


上面代码中的 worker.postMessage(subs) 这一行代码,最终将数值传给了 ‌Web Worker 线程‌。

具体来说,这行代码执行时:

  1. 创建了一个名为 worker 的 Web Worker 对象(通过 new Worker("kwb.js")

  2. 通过 worker.postMessage(subs) 将拼接好的字符串 subs 发送给这个 Web Worker 线程

  3. 这个字符串 subs 包含了从 HTML 页面获取的两个数字,格式为 "数字1@数字2"

  4. Web Worker 线程中的 onmessage 事件处理函数会接收到这个消息,然后进行计算处理

所以这个 postMessage 调用是将数据从主线程发送到 Web Worker 线程的通信机制。


那这一个先传还是计算好的和的值先传给线程?


数据传输和计算的顺序是:

  1. 首先‌:主线程中的 kwb() 函数获取HTML页面中输入框的值

  2. 然后‌:将这些值通过 worker.postMessage(subs) 发送给Web Worker线程

  3. 接着‌:Web Worker线程接收到数据后开始执行计算

  4. 最后‌:计算完成后,通过 postMessage(result) 将结果传回主线程

所以是‌数据先传给线程‌,然后线程进行计算,计算完成后再将结果传回主线程。

这个过程体现了Web Worker异步处理的特点:主线程发送数据 → Worker线程处理计算 → Worker线程返回结果。


标签: