blog icon indicating copy to clipboard operation
blog copied to clipboard

浏览器在同js文件下执行后台线程Worker

Open chenshenhai opened this issue 5 years ago • 0 comments

??????

??????js???Worker???????????????????????????????????????????????????worker.js??????????????????????????????????????????

???????????????????????????????????????work.js????????????????????????js???????????????????????????????????????????????????????????????MDN ??????????????????????????????js???????????????????????????Worker??????????????????????????????

??????

????????????

/**
 * ???????????????????????????
 * @param func ??????????????????????????????
 * @param params ????????????????????????????????????
 * @param feedback ?????????????????????????????????????????????
 */
 const asyncWorker = function (func, params, feedback) {
   // ???????????????????????????UUID
  const uuid = Math.random().toString(26).substr(2);

  // ?????????????????????????????????
  const scriptCode = `(${func.toString()})(event.data.params)`;
  const feedbackMap = new Map();
  // ???????????????????????????
  const workerCode = `
    onmessage = function (event) {
      let result = null;
      let err = null;
      result = eval(event.data.code);
      postMessage({
        id: event.data.id,
        result: result,
        error: err,
      });
    }
  `;
  const workerCodeStr = encodeURIComponent(workerCode);
  // ?????????????????????
  const worker = new Worker('data:text/javascript;charset=US-ASCII,' + workerCodeStr);

  // ??????????????????????????????
  worker.onmessage = function (event) {
    const callback = feedbackMap.get(event.data.id);
    if (typeof callback === 'function') {
      callback(event.data.result, event.data.error);
    }
    feedbackMap.delete(event.data.id);
  };

  // ????????????????????????
  worker.onerror = function (err) {
    const callback = feedbackMap.get(uuid);
    if (typeof callback === 'function') {
      callback(null, err.message);
    }
    feedbackMap.delete(uuid);
  };

  // ???????????????map???
  feedbackMap.set(uuid, feedback);

  // ?????????????????????ID???UUID?????????
  worker.postMessage({
    id: uuid,
    params: params,
    code: scriptCode
  });
};

????????????????????????

// ??????????????????????????????
// ????????????????????????
const fibonacciFunc = function(params = {}) {
  const { count = 1 } = params;
  let result = 1;
  for (let i = 0; i < count; i ++) {
    result += result;
  }
  return result;
}
// ?????????????????????????????? 50
const params = { count: 50 };
// ???????????????????????? ????????????
asyncWorker(fibonacciFunc, params, function (result, err) {
  console.log('result = ', result);
  console.log('error = ', err);
});
????????????
# ?????????????????? ????????????
result =  1125899906842624
error =  null

????????????????????????

// ???????????????????????? ????????????
const errorFunc = function(params = {}) {
  throw new Error('i am an error')
}
// ???????????????????????? ????????????
asyncWorker(errorFunc, {}, function (result, err) {
  console.log('result = ', result);
  console.log('error = ', err);
});
????????????
result =  null
error =  Uncaught Error: i am an error

??????

MDN:Web/API/Web_Workers_API/Using_web_workers

chenshenhai avatar Jun 24 '19 14:06 chenshenhai