当我在我的 Web worker 上调用终止时,它处于什么状态

When I call terminate on my web worker what state is it in?

本文关键字:于什么 状态 什么 我的 Web worker 终止 调用      更新时间:2023-09-26

我有一个网络工作者,我用它来轮询信息。

以下是用于启动和停止 Web 辅助角色的代码:

var eftWorker = undefined;
that.StartWorker = function () {
    if (eftWorker === undefined) {
        eftWorker = new Worker('../scripts/ETEL.EftWorker.js');
        eftWorker.addEventListener('message', function(e) {
            EftWorkerResponseHandler(e.data);
        }, false);
        eftWorker.addEventListener('error', function(e) {
            EftWorkerErrorResponseHandler(e);
        }, false);
    }
    eftWorker.postMessage({ cmd: eftCmdStart });
};
that.StopWorker = function () {
    if (eftWorker !== undefined) {
        eftWorker.postMessage({ cmd: eftCmdStop });
        eftWorker.terminate();
    }
    eftWorker = undefined;
};

当我在工作线程上调用终止时,因为工作线程正在轮询,似乎积压了未处理的帖子事件。

我在初始化包含视图和终止 Web 工作线程时将 Web 工作线程设置为"未定义"。我相信由于后者,那些未处理的事件显示为ABORT_ERRORs。是否有一个中间状态可以用来测试 Web worker 的存在,以便我可以允许它处理未完成的事件,从而避免错误?

或者,我可以使用其他方法来避免调用终止后累积错误?

这是我对问题的解决方案。

我将工作线程的状态记录在一个单独的变量中,以便我可以保持活动状态以处理导致错误的未完成消息。

此外,我正在捕获并丢弃在工人本身内部生成的任何错误。

var eftWorker = undefined;
var eftWorkerState = undefined;
var workerStateStarted = 'started';
var workerStateStopped = 'stopped';
var StartWorker = function () {
    if (eftWorker === undefined | eftWorkerState !== workerStateStarted) {
        eftWorker = new Worker('/scripts/ETEL.EftWorker.js');
        eftWorker.addEventListener('message', function(e) {
            EftWorkerResponseHandler(e.data);
        }, false);
        eftWorker.addEventListener('error', function (e) {
            EftWorkerErrorResponseHandler(e);
        }, false);
    }
    eftWorker.postMessage({ cmd: eftCmdStart });
    eftWorkerState = workerStateStarted;
};
that.StopWorker = function () {
    if (eftWorker !== undefined) {
        eftWorker.postMessage({ cmd: eftCmdStop });
        eftWorker.terminate();
    }
    eftWorkerState = workerStateStopped;
    //eftWorker = undefined;
};
var EftWorkerResponseHandler = function (msg) {
    try {
        if (eftWorkerState === workerStateStarted) {
            if (msg != '' && msg !== undefined) {
                var parser = new DOMParser();
                var xmlDoc = parser.parseFromString(msg, 'text/xml');
                var json = $.xmlToJSON(xmlDoc);
                AlterPaymentUIAccordingToEftWorkerStatus(json);
            }
        }
    } catch (exception) { }
};

这是负责发回状态消息的工作人员的代码。

EftSendGetRequest = function(passedUrl) {
    if (xmlHttpReq === undefined) {
        xmlHttpReq = new XMLHttpRequest();
    }
    try {
        xmlHttpReq.open("GET", passedUrl, false);
        xmlHttpReq.send();
    } catch (e) { }
    return xmlHttpReq.responseText;
};

这很旧,但我在寻找不同答案时正在查看它。

为什么不让工人处理自己的状态和终止呢? 最初的问题是如何让工作人员完成未完成的请求。 因此,让它完成其请求并指示何时完成。

如果 JavaScript 是这样的:

var eftWorker = undefined;
var StartWorker = function () {
    if (eftWorker === undefined) {
        eftWorker = new Worker('/scripts/ETEL.EftWorker.js');
        eftWorker.addEventListener('message', function(e) {
            EftWorkerResponseHandler(e.data);
        }, false);
        eftWorker.addEventListener('error', function (e) {
            EftWorkerErrorResponseHandler(e);
        }, false);
        // i'm assuming we don't want to trigger start multiple times,
        // so this is moved inside the IF.
        eftWorker.postMessage({ cmd: eftCmdStart });
    }
};
that.StopWorker = function () {
    if (eftWorker !== undefined) {
        eftWorker.postMessage({ cmd: eftCmdStop });
    }
};
var EftWorkerResponseHandler = function (msg) {
    try {
        if (msg && msg === 'readyToTerminate') {
            eftWorker.terminate();
            eftWorker = undefined;
        } else {
            // handle other situations.
        }
    } catch (exception) { }
};

工人是这样的:

;(function(self, undefined) {
    var receivedStopCmd = false;
    self.addEventListener('message', function(e){
        if (e.data.cmd === 'eftCmdStart') {
            // kick off processing here
            EftSendGetRequest('...');
        }
        if (e.data.cmd === 'eftCmdStop') {
            // xhr might be in process, this just updates what
            // the onload function does.
            receivedStopCmd = true;
        }
    }, false);

    var EftSendGetRequest = function(passedUrl) {
        if (xmlHttpReq === undefined) {
            xmlHttpReq = new XMLHttpRequest();
        }
        try {
            xmlHttpReq.open("GET", passedUrl, false);
            xmlHttpReq.onload = function(){
                if (!receivedStopCmd) {
                    // post response and/or keep polling
                    self.postMessage('whatever the message is');
                } else {
                    // (1) stop polling so no more 
                    //     requests are sent..if this 
                    //     requires doing anyhting
                    // (2) Send a message that this worker can be terminated.
                    self.postMessage('readyToTerminate');
                }
            };
            xmlHttpReq.send();
        } catch (e) { }
        return xmlHttpReq.responseText;
    };
})(self);

这将使XHR能够自我管理。 我当然没有运行这个..这只是我将对这个问题采取的方法的一个例子。