【问题标题】:Using web worker for api calls使用 web worker 进行 api 调用
【发布时间】:2017-11-06 10:23:59
【问题描述】:

我正在尝试找出一种干净的方式来使用网络工作者来执行 api 调用,到目前为止,我已经在客户端进行了此操作:

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

所以这个函数可以从客户端调用并给定一些参数。 内部网络工作者本身

worker-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
);

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

【问题讨论】:

    标签: javascript multithreading asynchronous ecmascript-6 web-worker


    【解决方案1】:

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

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

    2. 如果担心冒泡,应将addEventListener中的useCapture设置为true,并使用stopPropagation防止冒泡给孩子

    3. 您假设所有 fetch 调用按顺序返回。既然您要卸载给工人,就不能再保证这一点。所以你需要用某种标识符标记每个请求。

    您如何实施 #3 将有待商榷。如果您关注性能,您可能需要研究一些性能 UUID 生成器。

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

    【讨论】:

    • 这是一个有用且被接受的答案 - 不知道为什么没有超过 140 个视图的支持
    猜你喜欢
    • 2018-12-07
    • 2019-11-04
    • 1970-01-01
    • 2014-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-15
    • 1970-01-01
    相关资源
    最近更新 更多