blog
blog copied to clipboard
浏览器在同js文件下执行后台线程Worker
??????
??????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