@minto-ai/xunfei-tts
Version:
借助“讯飞在线语音合成API”实现浏览器端“文本转语音
174 lines (149 loc) • 4.74 kB
text/typescript
import type { PrivateCustomEventName } from '../../types'
import type { ParallelTaskExecuteContext, ParallelTaskItem } from '../types'
import { getUuid } from '@minto-ai/tools'
import { createEventBus } from '../../utils'
import { BaseHandler } from '../core'
import { ParallelHandlerStatus, ParallelTaskItemStatus } from '../types'
const $bus = createEventBus<PrivateCustomEventName>()
/**
* 并行任务处理器 - 并行处理队列中的任务
*
* 特点:
* - 支持并行执行任务
* - 支持任务执行前的自定义条件检查
* - 实现完整的生命周期管理(激活、待机、执行、成功、销毁)
* - 可与其他处理器组成处理链
*
* 使用场景:
* - 需要并行执行的任务处理
* - 资源充足且任务独立的场景
*/
abstract class ParallelFactory<O, R> extends BaseHandler<O, R> {
/**
* 获取待处理任务数量
*/
protected taskQueue: Array<ParallelTaskItem<O>> = []
/**
* 当前处理器状态
*/
public handlerStatus: ParallelHandlerStatus = ParallelHandlerStatus.OFFLINE
/**
* 待处理任务队列
*/
public get taskQueueLength(): number {
return this.taskQueue.length
}
constructor() {
super()
}
/**
* 检查任务执行条件
* 子类可重写此方法,实现自定义的任务执行前置条件检查
*
* @returns {boolean} - 当满足执行条件时返回 true,否则返回 false
*/
public executePreCheck(): boolean {
return true
}
/**
* 触发处理器激活行为(空闲状态 => 激活状态)
*/
public triggerHandlerActive(): void {
this.setHandlerStatus(ParallelHandlerStatus.ACTIVE)
this.onActive()
this.triggerHandlerPending()
}
/**
* 触发处理器待机行为(激活状态 => 待执行状态)
*/
public triggerHandlerPending(): void {
this.setHandlerStatus(ParallelHandlerStatus.PENDING)
}
/**
* 触发处理器执行行为(激活状态 => 执行状态)
*/
public async triggerHandlerExecute(): Promise<void> {
this.setHandlerStatus(ParallelHandlerStatus.EXECUTING)
Promise.resolve().then(() => {
this.taskQueue
.filter(({ status }) => status === ParallelTaskItemStatus.PENDING)
.forEach((taskItem) => {
taskItem.status = ParallelTaskItemStatus.EXECUTING
const isFirstExecute = this.isFirstExecute
if (isFirstExecute) {
this.isFirstExecute = false
this.onBeforeFirstExecute()
}
let isLastExecute = false
if (
this.isHandleDataAcceptedComplete
&& this.taskQueue.every(({ status }) => status !== ParallelTaskItemStatus.PENDING)
) {
isLastExecute = true
}
const context = {
taskItem,
isFirstExecute,
isLastExecute,
} as ParallelTaskExecuteContext<O, R>
this.execute(context)
})
})
}
public handle(original: O): void {
this.taskQueue.push({
uuid: getUuid(),
original,
status: ParallelTaskItemStatus.PENDING,
})
if (!this.executePreCheck()) {
this.setHandlerStatus(ParallelHandlerStatus.PENDING)
return
}
this.triggerHandlerExecute()
}
/**
* 处理队列
*/
public taskCompletedCallback(uuid: string): void {
const taskIndex = this.taskQueue.findIndex(item => item.uuid === uuid)
if (taskIndex !== -1) {
this.taskQueue[taskIndex].status = ParallelTaskItemStatus.COMPLETED
this.taskQueue.splice(taskIndex, 1)
}
if (this.isHandleDataAcceptedComplete && this.taskQueue.length === 0) {
this.triggerHandlerCompleted()
if (this.isLastHandler) {
this.triggerAppFinish()
}
}
}
/**
* 触发处理器成功行为(执行状态 => 成功状态)
*/
public triggerHandlerCompleted(): void {
this.setHandlerStatus(ParallelHandlerStatus.COMPLETED)
if (this.nextHandler) {
this.nextHandler.handle(null)
this.nextHandler.isHandleDataAcceptedComplete = true
}
this.onCompleted()
}
/**
* 触发处理器销毁行为(待机状态 => 销毁状态)
*/
public triggerHandlerFinish(): void {
this.taskQueue = []
this.isFirstExecute = true
this.isHandleDataAcceptedComplete = false
this.setHandlerStatus(ParallelHandlerStatus.FINISH)
this.onFinish()
}
/**
* 触发应用被销毁行为
*/
public triggerAppFinish(): void {
$bus.emit('_appFinish')
}
}
export default ParallelFactory