如何通过 worker.onerror 冒泡 promise 中的 web worker 错误?

How to bubble a web worker error in a promise via worker.onerror?

我正在处理一个需要在发生错误时进行报告的网络工作者。通常,我可以使用 worker.onerror 来监听从工作人员抛出的任何错误。但是,当错误发生在网络工作者的承诺中时,我无法弄清楚如何将错误冒泡回 worker.onerror.

请原谅奇怪的代码片段,因为这似乎是展示工作人员行为的唯一方法。 (工人在 HTML 部分中定义)。

function getInlineJS() {
  var js = document.querySelector('[type="javascript/worker"]').textContent;
  var blob = new Blob([js], {
    "type": "text\/plain"
  });
  return URL.createObjectURL(blob);
}

var worker = new Worker(getInlineJS());

worker.onerror = function(err) {
  document.getElementById('errors').innerHTML += 
    "error " + err.message + '\n';
}

worker.onmessage = function (msg) {
  console.log("message recieved", msg);
  document.getElementById('messages').innerHTML += 
    "message " + msg.data + '\n';
}


worker.postMessage("run");
worker.postMessage("promise");
should write "Normal Error and In Promise Error" below and in console (promise error only occurs in console though): <br>

<pre id="errors">
</pre>

messages:
<pre id="messages">
</pre>

<script type="javascript/worker">
self.addEventListener("message", function(e) {
    /* demonstration of normal error bubbling to onerror */
    if (e.data == 'run') {
      throw new Error('Normal Error');
      return;
    }
    new Promise(function(resolve, reject) {
      /* some logic that breaks */
      throw new Error('In Promise Error');
    }).then(function(result) {
      
    }).catch(function(err) {
      /* QUESTION: HOW TO GET THIS ERROR OUT OF WORKER? */
      
      /* it logs to console just fine */
      console.log("In Promise Catch Error:", err);
      
      /* postMessage doesn't work for some reason */
      self.postMessage({error: err});
      
      /* and this doesn't bubble it to worker.onerror */
      throw err; /* doesn't bubble!! */
    });
});
</script>

如何检索发生在 promises 中的 Web Worker 错误?

postMessage doesn't work for some reason

那是因为你要返回一个对象而不是字符串,将其更改为 self.postMessage({error: err.message});

至于你的第二个问题,你可以使用setTimeout(function() { throw err; });技巧。可以找到有关情况和技巧的更多信息 here

function getInlineJS() {
  var js = document.querySelector('[type="javascript/worker"]').textContent;
  var blob = new Blob([js], {
    "type": "text\/plain"
  });
  return URL.createObjectURL(blob);
}

var worker = new Worker(getInlineJS());

worker.onerror = function(err) {
  document.getElementById('errors').innerHTML += 
    "error " + err.message + '\n';
}

worker.onmessage = function (msg) {
  console.log("message recieved", msg);
  document.getElementById('messages').innerHTML += 
    "message " + msg.data + '\n';
}


worker.postMessage("run");
worker.postMessage("promise");
should write "Normal Error and In Promise Error" below and in console (promise error only occurs in console though): <br>

<pre id="errors">
</pre>

messages:
<pre id="messages">
</pre>

<script type="javascript/worker">
self.addEventListener("message", function(e) {
    /* demonstration of normal error bubbling to onerror */
    if (e.data == 'run') {
      throw new Error('Normal Error');
      return;
    }
    new Promise(function(resolve, reject) {
      /* some logic that breaks */
    
      throw new Error('In Promise Error');
    }).then(function(result) {
      
    }).catch(function(err) {
      /* it logs to console just fine */
      console.log("In Promise Catch Error:", err);
      
      /* postMessage works when you return a string. */
      self.postMessage({error: err.message});

       setTimeout(function() { throw err; }); 
    });
});
</script>