如果我向同一个 webworker 发送多条消息,它会 queue 它们并按顺序处理它们吗?
If i send multiple messages to the same webworker, does it queue them up and process them sequentially?
正如标题所说...
基本上,如果我有一个网络工作者并且 post 它一次处理 1000 条消息。
每条消息都会导致工作人员执行处理密集型操作。
我最好是在前一个消息完成后 post 将每条消息按顺序发送给 webworker,还是我可以安全地将所有请求发送给 worker,因为他们知道它们将被一个接一个地处理和返回当他们完成时?
如果我这样做,我是否最好在工作人员中实施排队系统?还是没有必要?
我知道这个 worker 只是一个线程,因此 javascript 操作确实会在 webworker 本身内同步发生,但我担心以类似的方式执行 200 [=25] 的争用=] 一次请求会使浏览器不堪重负。
希望如此。
Web Worker 一次接收每条消息 - 任何排队都将由您自己的逻辑完成 - 为了速度最好将数据作为类型化数组传输,尤其是称为可传输对象的形式 - 可能您可以放置许多(1000 ) 消息到这样一个类型化的数组(float 或 int)并使它成为一个单一的消息 - 从浏览器到 Web Worker 的实际数据传输或从浏览器到 Web Worker 的实际数据传输非常快 - 10 兆字节的类型化数组以毫秒或更短的时间......这个消息确实也能处理对象,尽管与低级类型数组相比速度有所下降
worker 将对消息进行排队(具体来说,它将对 onmessage
的调用进行排队)并在 worker 的调用堆栈为空时处理每条消息。
但是,这意味着异步操作可能会导致在任何特定操作完成之前处理输入的多条消息。例如:
onmessage = function(e) {
var xhr = new XMLHttpRequest();
xhr.open("GET", "/" + e.data);
xhr.onload = function() {
postMessage(xhr.responseText);
}
}
如果您一次传递 1000 条消息,我怀疑浏览器会在它之前触发 1000 Ajax 个请求(或至少很多请求)运行s postMessage
onload
内。这是因为 onload
在 Ajax 调用完成之前不会 运行,并且每个 onload
调用都将添加到对 [=12= 的任何未决调用之后的事件队列中] 在 Ajax 提取完成之前被请求。
如果您想确保一次只有一个 Ajax 请求发出,您确实可以实现一个仅在调用 onload
时才移动的内部队列:
var queue = [];
var busy = false;
onmessage = function(e) {
if(busy) {
queue.push(e);
}
else {
busy = true;
runAjax(e);
}
}
var runAjax = function(e) {
var xhr = new XMLHttpRequest();
xhr.open("GET", e.data);
xhr.onload = function() {
postMessage(xhr.responseText);
if(queue.length) {
// run the next queued item
runAjax(queue.shift());
} else {
busy = false;
}
}
}
在这种情况下,第一条消息进入 else
块,它设置 busy = true
和 运行s Ajax 提取。以下 999 条消息被路由到 if
块,因为 busy
是 true
(并且在 Ajax 请求完成之前不会变成 false
and queue
为空)。只有在 Ajax 请求完成后才会处理排队的消息。
如果你当时想容忍多个 Ajax 请求,你可以使用计数器而不是布尔值:使用 busy++
和 busy--
而不是设置 true
和 false
,并测试当前未完成的连接数是否未达到允许的最大值(即 if(busy == 5)
而不是 if(busy)
)。
正如标题所说...
基本上,如果我有一个网络工作者并且 post 它一次处理 1000 条消息。
每条消息都会导致工作人员执行处理密集型操作。
我最好是在前一个消息完成后 post 将每条消息按顺序发送给 webworker,还是我可以安全地将所有请求发送给 worker,因为他们知道它们将被一个接一个地处理和返回当他们完成时?
如果我这样做,我是否最好在工作人员中实施排队系统?还是没有必要?
我知道这个 worker 只是一个线程,因此 javascript 操作确实会在 webworker 本身内同步发生,但我担心以类似的方式执行 200 [=25] 的争用=] 一次请求会使浏览器不堪重负。
希望如此。
Web Worker 一次接收每条消息 - 任何排队都将由您自己的逻辑完成 - 为了速度最好将数据作为类型化数组传输,尤其是称为可传输对象的形式 - 可能您可以放置许多(1000 ) 消息到这样一个类型化的数组(float 或 int)并使它成为一个单一的消息 - 从浏览器到 Web Worker 的实际数据传输或从浏览器到 Web Worker 的实际数据传输非常快 - 10 兆字节的类型化数组以毫秒或更短的时间......这个消息确实也能处理对象,尽管与低级类型数组相比速度有所下降
worker 将对消息进行排队(具体来说,它将对 onmessage
的调用进行排队)并在 worker 的调用堆栈为空时处理每条消息。
但是,这意味着异步操作可能会导致在任何特定操作完成之前处理输入的多条消息。例如:
onmessage = function(e) {
var xhr = new XMLHttpRequest();
xhr.open("GET", "/" + e.data);
xhr.onload = function() {
postMessage(xhr.responseText);
}
}
如果您一次传递 1000 条消息,我怀疑浏览器会在它之前触发 1000 Ajax 个请求(或至少很多请求)运行s postMessage
onload
内。这是因为 onload
在 Ajax 调用完成之前不会 运行,并且每个 onload
调用都将添加到对 [=12= 的任何未决调用之后的事件队列中] 在 Ajax 提取完成之前被请求。
如果您想确保一次只有一个 Ajax 请求发出,您确实可以实现一个仅在调用 onload
时才移动的内部队列:
var queue = [];
var busy = false;
onmessage = function(e) {
if(busy) {
queue.push(e);
}
else {
busy = true;
runAjax(e);
}
}
var runAjax = function(e) {
var xhr = new XMLHttpRequest();
xhr.open("GET", e.data);
xhr.onload = function() {
postMessage(xhr.responseText);
if(queue.length) {
// run the next queued item
runAjax(queue.shift());
} else {
busy = false;
}
}
}
在这种情况下,第一条消息进入 else
块,它设置 busy = true
和 运行s Ajax 提取。以下 999 条消息被路由到 if
块,因为 busy
是 true
(并且在 Ajax 请求完成之前不会变成 false
and queue
为空)。只有在 Ajax 请求完成后才会处理排队的消息。
如果你当时想容忍多个 Ajax 请求,你可以使用计数器而不是布尔值:使用 busy++
和 busy--
而不是设置 true
和 false
,并测试当前未完成的连接数是否未达到允许的最大值(即 if(busy == 5)
而不是 if(busy)
)。