Worker

198 阅读1分钟

1、创建一个worker

function createWorker(f) {
  // [使用 Blob 创建一个指向类型化数组的URL]
  const blob = new Blob([`(${f.toString()})();`]);
  const url = window.URL.createObjectURL(blob);
  const worker = new Worker(url); // url 为指定的要运行的脚本
  return worker;
}

2、要执行的脚本

function createWorkerFunString() {
  return `
  function () {
    importScripts("${url}sdk/xe-utils.js");
    importScripts("${url}sdk/runFormula.js");
    const runFormula = library_runFormula.runFormula
    self.onmessage = e => {
      let { data } = e;
       data = JSON.parse(data);
       try {
        console.time('time');
        runFormula(data)
        console.timeEnd('time'); 
      } catch (e) {
        console.error(e);
      }
      console.log(data)
      self.postMessage(data);
    };
  }`;
}

3、创建一个类,可多次执行不同的脚本

class RunFormulaAsync {
  poolIndex = 0;
  poolLimit = 6;
  executing = [];
  workers = [];
  tasks = [];
  constructor() {}
  runFormula(data) {
    return new Promise(resolve => {
      this.tasks.push({
        data: JSON.stringify(data),
        resolve
      });
      this.run();
    });
  }
  run() {
    if (!this.workers.length && this.poolIndex < this.poolLimit) {
      ++this.poolIndex;
      this.workers.push(createWorker(createWorkerFunString()));
    }
    if (!this.workers.length || !this.tasks.length) {
      return;
    }
    const worker = this.workers.shift();
    const task = this.tasks.shift();
    worker.postMessage(task.data);
    worker.onmessage = e => {
      task.resolve(e.data);
      this.workers.push(worker);
      this.run();
    };
  }
  init() {
    while (this.poolIndex < this.poolLimit) {
      ++this.poolIndex;
      this.workers.push(createWorker(createWorkerFunString()));
    }
  }
}
const runFormulaAsync = new RunFormulaAsync();
export default runFormulaAsync;