0

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

下面是启动和停止 web worker 的代码:

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;
};

当我在工作人员上调用终止时,因为工作人员正在轮询,似乎有未处理的消息后事件积压。

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

或者是否有一种不同的方法可以用来避免在调用终止后累积错误?

4

2 回答 2

0

这是旧的,但我在寻找不同的答案时正在查看它..

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

如果 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 进行自我管理。我当然没有运行这个..它只是我在这个问题上采取的方法的一个例子。

于 2014-12-11T14:50:17.853 回答
0

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

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

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

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;
};
于 2013-09-05T14:13:57.937 回答