在 web worker 中注册事件监听器

Register event listeners in web worker

是否可以在 Web Worker 中为 'message''error' 以外的事件注册监听器?例如

addEventListener('keydown', function (e) {
  postMessage('test');
});

编辑:

根据@T.J.Crowder,这是不可能的。但是,就我而言,我能够通过消息来模拟它,就像这样:

在工人中:

const handlers = {};

function registerKeyHandler(keycode, callback) {
  postMessage({
    type: 'REGISTER_KEY_HANDLER',
    keycode: keycode,
  });

  handlers[keycode] = handlers[keycode] || [];
  handlers[keycode].push(callback);
}

function onKeydown(keycode) {
  const hs = handlers[keycode] || [];
  hs.forEach(h => h());
}

self.onmessage = function(msg) {
  switch (msg.type) {
    case 'KEYDOWN':
      onKeydown(msg.payload.keycode);
      break;
  }
};

外面:

worker.onmessage = function(msg) {
  switch (msg.type) {
    case 'REGISTER_KEY_HANDLER':
      window.addEventListener('keydown', function (e) {
        if (e.keyCode !== msg.keycode) {
          return;
        }
        worker.postMessage({
          type: 'KEYDOWN',
          keycode: msg.keycode,
        });
      });
      break;
  }
};

没有。 Web 工作者无法访问 DOM,尤其是因为

  • 允许多个线程访问 DOM 会打开 browser-based 代码,导致 class 的 multi-threading 错误;只允许主 UI 线程更新 DOM 避免
  • 一些浏览器的 DOM 实现无法处理来自多个线程的访问

global scope object* workers have isn't a window and only has the minimal features called out by the web workers specification,例如 addEventListener(虽然很奇怪,它只是在规范中顺便提及)、postMessageonmessageonerror属性等

* (这是普通的,有dedicated [for Worker] and shared [for SharedWorker] sub-interfaces 取决于worker类型)