fineui是帆软报表和BI产品线所使用的前端框架。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

132 lines
3.8 KiB

import type { IWorkerController, IWorkerMessage } from '../worker.core';
import { WorkerChannel } from '../worker.channel';
/**
*
*
* @class WorkerBaseController
*/
export default class WorkerBaseController implements IWorkerController {
/**
* worker,
*/
protected worker: Worker;
/**
* Channel,
*/
protected channel: WorkerChannel;
/**
* Map
*/
protected actionHandlerMap: {
[propsName: string]: (payload: any) => any;
};
public constructor() {
this.actionHandlerMap = {};
}
/**
*
*
* @param actionType
* @param payload
*/
public request(actionType: string, payload: any): void {
if (this.channel) {
return this.channel.request(actionType, payload);
}
console.error('No channel.');
return;
}
/**
* Promise , then
*
* @param actionType
* @param payload
* @param [timeout] ; Worker , ,
*/
public requestPromise<T = any>(actionType: string, payload: any = '', timeout?: number): Promise<T> {
// 有 Channel 实例才能进行通信, 此时还没有实例化是浏览器不支持创建 worker
if (this.channel) {
return this.channel.requestPromise<T>(actionType, payload, timeout);
}
// 兼容上层调用的 .then().catch()
return Promise.reject(new Error('No channel.'));
}
/**
* ,
*
* @param actionType
* @param handler
*/
public addActionHandler(actionType: string, handler: (payload: any) => any): void {
if (this.hasActionHandler(actionType)) {
throw new Error(`Add action \`${actionType}\` handler repeat`);
}
this.actionHandlerMap[actionType] = handler;
}
/**
* , Channel
*
* @param message
* @returns
*/
public actionHandler(message: IWorkerMessage): Promise<any> {
const { actionType, payload } = message;
if (this.hasActionHandler(actionType)) {
// 执行指定的事务处理器, 并返回 Promise 封装的事务结果
try {
const actionResult = this.actionHandlerMap[actionType](payload);
// 对于 Promise 形式的结果, 需要进行 Promise 错误捕获
if (BI.isPromise(actionResult)) {
return actionResult.catch(error => Promise.reject(error));
}
// 对数据结果, 包装为 Promise
return Promise.resolve(actionResult);
} catch (error) {
// 继续抛出给外层
return Promise.reject(error);
}
} else {
throw new Error(`Not Found Session Handler \`${actionType}\`.`);
}
}
/**
* worker onmessage
*
* @param {(event: any) => void} onmessage
* @returns {() => void}
*/
public addOnmessageListener(onmessage: (event: any) => void): () => void {
this.worker.addEventListener('message', onmessage);
// 返回移除监听函数
return () => {
this.worker.removeEventListener('message', onmessage);
};
}
/**
*
*
* @param actionType
* @returns {boolean}
*/
protected hasActionHandler(actionType: string): boolean {
return !!this.actionHandlerMap[actionType];
}
}