前端项目中使用Web Worker的具体实现
程序员文章站
2022-03-01 12:39:38
...
1 实际项目中使用Web Worker
下面这篇文章详细介绍了web worker常用的api, 场景(这里不知道有没有具体衡量指标),使用过程中的注意事项,文章写的很好,感兴趣可以看下,这里不在详细叙述具体概念
Web Worker使用
1.1 场景
这里分享的一个场景,是把从数据查询接口获取的数据的格式化过程放在web worker中执行。
首先简单介绍下我们的项目,一个可视化相关项目,接口主要分为两大方面,配置查询和数据查询接口,其中数据查询接口是影响页面性能指标的一个很关键的因素,并且从查询接口获取到数据之后的格式化过程逻辑全部放在fe中,数据格式化这个过程可能涉及一些比较大的计算,因此我们选择将它拆出来放在一个单独web worker线程中,减少对主线程造成影响。
1.2 实现
具体解释看注释
// workerHelper.ts
import Worker from 'worker-loader?inline=no-fallback!./query.worker.ts';
import axios, { CancelTokenSource } from 'axios';
import { ErrorType } from '@/api';
const { CancelToken } = axios;
type EventHanler = {
resolve: (value: any) => void;
reject: (reason?: any) => void;
};
export enum ErrorType {
TIMEOUT,
REQUEST,
CANCEL
}
const requestMap = new Map<string, CancelTokenSource>();
// 调用接口
const query = async (
params,
) => {
let resultData;
await axios.post(`******`, params, {
headers: {},
cancelToken: cancelToken.token,
})
.then(res => {
if (res.status === 200 && res.data.code === 0) {
resultData = res.data.data;
} else if (res.status === 404) {
throw 'request 404';
} else {
throw {
message: res.data.msg || res.statusText || '',
logId,
};
}
})
.catch(err => {
// 不是手动取消
const errType = err.__CANCEL__
? ErrorType.CANCEL
: (err.message ?? err)?.includes('timeout')
? ErrorType.TIMEOUT
: ErrorType.REQUEST;
const message = errType === ErrorType.TIMEOUT ? 'request timeout' : err.message ?? err;
const logId = err.logId ?? '';
throw {
message,
type: errType,
logId,
};
});
return resultData;
};
export default class WorkerHelper {
private static _worker: Worker | null; // 定义一个worker
// 初始化
static init() {
if (!this._worker) {
// 注册一个数据格式化worker
this._worker = new Worker();
// webworker异常
this._worker.addEventListener('error', e => {
throw e;
});
}
}
// 查询函数,对外提供
static query<T = any>(
params: any,
): Promise<T> {
return new Promise((resolve, reject) => {
// 如果未初始化,初始化
this.init();
query(params)
.then(data => {
// 查询到数据之后给worker发送消息启动格式化数据线程
this._worker?.postMessage({
method: 'format',
options: {
id,
data,
type,
params,
lang: getCurrentLang()
},
});
})
.catch((e: Error) => {
});
});
}
/**
*
* @param id 组件id
*/
static cancelQuery(id: string) {
requestMap.get(id as string)?.cancel();
}
/**
*
* @param 批量取消
*/
static cancelMoreQuery(ids: string[]) {
for(let id of ids){
requestMap.get(id as string)?.cancel();
}
}
// 终止worker
static terminate() {
this._worker?.terminate();
this._worker = null;
}
}
// 格式化worker
// query.worker.ts
interface QueryParams {
params: any;
}
interface CancelParams {
id: string;
}
const ctx: Worker = self as any;
const formatHandler = async options => {
const { data, id, type, params, lang } = options;
let result, error;
try {
if (!id) {
error = new Error('id 不存在');
throw error;
}
...
result = forMate(data)
} catch (e) {
error = e;
} finally {
ctx.postMessage({ id, data: result, error });
}
};
ctx.addEventListener(
'message',
(
event: MessageEvent<{
method: 'format' | 'cancelQuery';
options: QueryParams | CancelParams;
}>
) => {
const {
data: { method, options },
} = event;
if (method === 'format') {
// 格式化数据
formatHandler(options);
}
}
);
// 具体使用
import WorkerHelper from '@/utils/workerHelper';
...
const queryData = async (params) => {
isLoading.value = true;
const { data, series, delayedMessage, feQueryConfig, percent: percentConfig } = await WorkerHelper.query(
params,
);
...
};
...
推荐阅读
-
使用HTTP-REPL工具测试ASP.NET Core 2.2中的WEB API项目
-
eclipse Java web项目数据库由oracle更改为mysql中遇到的问题(使用JPA注解)附上修改过程
-
Web Worker在vue中的使用
-
动态网站项目(Dynamic Web Project)CRUD(增删改查)功能的实现(mvc(五层架构)+jdbc+servlet+tomcat7.0+jdk1.8),前端使用JSP+JSTL+EL组合
-
vue项目搭建通过vue-cli包括组件路由的使用实现基本的前端项目全流程
-
所谓的网页爬虫用java代码来实现,此代码适合在maven项目中使用中使用,因为,代码中的类所对应的依赖可以让maven下载。
-
yii2中使用webuploader实现图片上传的实战项目
-
使用css中的page-break-after属性来实现WEB页面强制分页打印
-
使用Sass优雅并高效的实现CSS中的垂直水平居中(附带Flex布局,CSS3+SASS完美版)_html/css_WEB-ITnose
-
使用Sass优雅并高效的实现CSS中的垂直水平居中(附带Flex布局,CSS3+SASS完美版)_html/css_WEB-ITnose