对于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