【问题标题】:When I call terminate on my web worker what state is it in?当我在我的网络工作者上调用终止时,它处于什么状态?
【发布时间】:2013-09-08 01:35:00
【问题描述】:

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

下面是启动和停止 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 的存在,以便我可以让它处理未完成的事件,从而避免错误?

或者有什么不同的方法可以用来避免调用终止后的错误累积?

【问题讨论】:

    标签: javascript jquery state web-worker terminate


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

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

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

      此外,我还捕获并丢弃了 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;
      };
      

      【讨论】:

      • 有趣的方法。但是如何跟踪被解雇工人的状态的问题仍然存在。导致行 //eftWorker = undefined; 的错误仍在您的代码中注释。
      猜你喜欢
      • 2016-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多