使用web worker进行api调用

Ilj*_*lja 3 javascript multithreading asynchronous web-worker ecmascript-6

我正试图找出一种干净的方式来使用网络工作者来执行api调用,到目前为止我在客户端有这个:

工人client.js

export const workerFetch = (method = "get", url = "/", data = {}) =>
  new Promise((resolve, reject) => {
    const listener = `worker_fetch_${url}_${new Date()}`;
    window.lootWorker.postMessage({
      cmd: "worker_fetch",
      payload: { method, url, data, listener }
    });
    window.addEventListener(
      "message",
      ({ data }) => {
        if (data.cmd === listener) {
          if (data.success) resolve(data.data);
          else reject(data.data);
        }
      },
      false
    );
  });
Run Code Online (Sandbox Code Playgroud)

所以这个函数可以从客户端调用并给出一些参数.内部web工作者本身

工人thread.js

const workerFetch = ({ method = "get", url = "", data = {}, listener = "" }) => {
  fetch({ method, url, data })
    .then(({ data }) => {
      self.postMessage({ cmd: `worker_fetch_${listener}`, success: true, data });
    })
    .catch(error => {
      self.postMessage({ cmd: `worker_fetch_${listener}`, success: false, data: error });
    });
};

self.addEventListener(
  "message",
  ({ data }) => {
    switch (data.cmd) {
      case "worker_fetch":
        workerFetch(data.payload);
        break;
      default:
        return null;
    }
  },
  false
);
Run Code Online (Sandbox Code Playgroud)

理论上这是有效的,但我担心在客户端冒泡这些事件监听,因此这个问题是否有一种通用的方法来实现这种关注性能的功能?毕竟我们这样做是为了从主线程中卸载一些东西.

Cod*_*gue 9

我对这种模式有一些保留意见:

  1. 请记住,只有响应的处理发生在另一个线程上,因此在卸载所有获取请求之前,您需要确保处理有效负载是一个瓶颈.

  2. 如果您担心冒泡,你应该设置useCapture在addEventListener以true和使用stopPropagation,防止起泡儿童

  3. 您假设所有提取调用按顺序返回.现在你正在卸载给工人,这已经无法保证了.因此,您需要使用某种标识符标记每个请求.

如何实施#3将引起争论.如果您专注于性能,您可能需要研究一些性能UUID生成器.

最后,似乎有一个npm包实现了这个功能:fetch-worker