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.
86 lines
2.4 KiB
86 lines
2.4 KiB
2 years ago
|
import { WorkerChannel } from "../worker.channel";
|
||
|
import type { IWorkerOptions } from "../worker.core";
|
||
|
import WorkerBaseController from "./worker.controller";
|
||
|
|
||
|
export class WorkerMainThreadController extends WorkerBaseController {
|
||
|
/**
|
||
|
* 浏览器是否实现了 HTML 规范的 Worker Class
|
||
|
*/
|
||
|
public static hasWorkerClass = !!_global.Worker;
|
||
|
|
||
|
/**
|
||
|
* 是否支持 new Worker, 默认为 Wroker Class 是否实现
|
||
|
*/
|
||
|
|
||
|
public canNewWorker: boolean = WorkerMainThreadController.hasWorkerClass;
|
||
|
|
||
|
/**
|
||
|
* 主线程 new Worker 起始时刻
|
||
|
*/
|
||
|
public timeBeforeNewWorker: number;
|
||
|
|
||
|
/**
|
||
|
* 主线程 new Worker 完毕时刻
|
||
|
*/
|
||
|
public timeAfterNewWorker: number;
|
||
|
|
||
|
public constructor(options: IWorkerOptions) {
|
||
|
super();
|
||
|
|
||
|
if (!this.canNewWorker) {
|
||
|
// 都没有 Worker Class, 没法继续了
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
this.newWorker(options);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 销毁 Worker 线程实例
|
||
|
*/
|
||
|
public terminate(): void {
|
||
|
this.worker?.terminate();
|
||
|
}
|
||
|
|
||
|
protected reportActionHandlerError(actionType: string, error: any): void {
|
||
|
console.error(`Worker aciton ${actionType}:`, error);
|
||
|
|
||
|
// 主线程的报错, 在 window.onerror 中可以拿到报错堆栈, 直接抛出即可
|
||
|
throw new Error(error);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 创建 Worker 线程实例
|
||
|
*/
|
||
|
private newWorker(options: IWorkerOptions) {
|
||
|
this.timeBeforeNewWorker = Date.now();
|
||
|
|
||
|
try {
|
||
|
// 主线程通过 new Worker() 获取 Worker 实例
|
||
|
this.worker = new Worker(options.workerUrl, {
|
||
|
name: options.workerName,
|
||
|
});
|
||
|
|
||
|
/**
|
||
|
* 监控和上报 worker 中的报错
|
||
|
* window.onerror 中也能监控到 worker.onerror( Worker 运行报错)
|
||
|
*/
|
||
|
this.worker.onerror = (error): void => {
|
||
|
console.error('Worker onerror:', error);
|
||
|
};
|
||
|
|
||
|
this.timeAfterNewWorker = Date.now();
|
||
|
|
||
|
// 实例化 Channel
|
||
|
this.channel = new WorkerChannel(this.worker, {
|
||
|
actionHandler: this.actionHandler.bind(this),
|
||
|
});
|
||
|
} catch (error) {
|
||
|
console.error('Init worker fail:', error);
|
||
|
|
||
|
// 创建 worker 失败, 标识改为不支持
|
||
|
this.canNewWorker = false;
|
||
|
}
|
||
|
}
|
||
|
}
|