import type { IWorkerController, IWorkerMessage } from '../worker.core'; import { WorkerChannel } from '../worker.channel'; /** * 通信控制器 * * @class WorkerBaseController */ export 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(actionType: string, payload: any = '', timeout?: number): Promise { // 有 Channel 实例才能进行通信, 此时还没有实例化是浏览器不支持创建 worker if (this.channel) { return this.channel.requestPromise(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 { 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]; } }