Open chenshenhai opened 5 years ago
对于js的Worker的使用,看了很多网上资料,都是基于worker.js新开一个文件来执行后台线程。
Worker
worker.js
但是如果不想太麻烦新开一个work.js文件,想在同一个js文件里执行后台线程的资料就很少,最后翻遍了MDN 文档,找到了一种在同js文件下执行后台线程Worker的方法,具体实现如下
work.js
/** * 执行函数的后台线程 * @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
前言
对于js的
Worker
的使用,看了很多网上资料,都是基于worker.js
新开一个文件来执行后台线程。但是如果不想太麻烦新开一个
work.js
文件,想在同一个js文件里执行后台线程的资料就很少,最后翻遍了MDN 文档,找到了一种在同js文件下执行后台线程Worker的方法,具体实现如下实现
实现源码
执行正常后台线程
执行结果
执行异常后台线程
执行结果
参考
MDN:Web/API/Web_Workers_API/Using_web_workers