如果我向同一个webworker发送多条消息,它会将它们排队并按顺序处理吗

If i send multiple messages to the same webworker, does it queue them up and process them sequentially?

本文关键字:排队 顺序处理 消息 同一个 webworker 如果      更新时间:2024-01-16

正如标题所说。。。

基本上,如果我有一个网络工作者,一次发布1000条消息。

每条消息都会导致工作人员执行处理密集型操作。

我最好在前一条消息完成后按顺序将每条消息发布到网络工作者,还是我可以安全地将所有请求发送给工作者,因为我知道它们在完成时会被逐一处理和返回?

如果我这样做,在员工内部实施排队系统会更好吗?还是没有必要?

我知道这个单独的worker只是一个单独的线程,因此javascript操作确实会在webworker本身中同步发生,但我担心的是,一次执行200个ajax请求会让浏览器不堪重负。

我希望这能成功。

工作程序将对消息进行排队(具体地说,它将对onmessage的调用进行排队),并在工作程序的调用堆栈为空时处理每条消息。

然而,这意味着异步操作可能会导致在任何特定操作完成之前处理输入的多条消息。例如:

onmessage = function(e) {
    var xhr = new XMLHttpRequest();
    xhr.open("GET", "/" + e.data);
    xhr.onload = function() {
        postMessage(xhr.responseText);
    }
}

如果一次传入1000条消息,我怀疑浏览器在onload中运行postMessage之前会发出1000个Ajax请求(或者至少会发出很多请求)。这是因为onload在Ajax调用完成之前不会运行,并且每个onload调用都将添加到事件队列中,位于Ajax获取完成之前请求的对onmessage的任何挂起调用之后。

如果您想确保一次只发出一个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并运行Ajax获取。以下999条消息被路由到if块,因为busytrue(并且在Ajax请求完成并且queue为空之前不会变成false)。排队的消息只有在Ajax请求完成后才能处理。

如果您想一次容忍多个Ajax请求,可以使用计数器而不是布尔值:使用busy++busy--而不是设置truefalse,并测试当前未完成连接的数量是否没有达到您允许的最大值(即if(busy == 5)而不是if(busy))。

Web Worker一次接收一条消息-任何排队都将由您自己的逻辑完成-为了加快以类型化数组的形式传输数据的速度,尤其是一种称为可传输对象的形式-您可能会将许多(1000)条消息放入这样的类型化数组(float或int)中,并使其成为单个消息-从浏览器到Web Worker的实际数据传输,反之亦然是一个非常快速的10兆字节数组,以毫秒或更短的时间。。。这种消息传递也能处理对象,尽管与低级别类型数组

相比速度会有所下降