整体上,把 “嘀嗒” “短间隔” “长间隔” 都转化成替代符,过滤无用的替代符,然后 filter “长间隔” 替代符的流,来做 buffer 切片数据。其他还有因为使用 combineLatest 操作符导致的不同。
// 识别 “嘀” “嗒”
const morseCharFromEvents$ = observableCombineLatest(this.startEvents$, this.stopEvents$)
.pipe(
// 计算 mousedown mouseup 时间间隔
map(this.toTimeDiff),
// 转化成标识符
map(this.msToMorseChar),
// 过滤 Morse 单元组中的 “短间隔“ 标识符
filter(this.isCharNoShortBreak as any)
);
// 主信号流
this.morseChar$ = observableMerge(morseCharFromEvents$, this.injectMorseChar$)
// 识别 “长间隔“ 标识符,来作为切片流
const longBreaks$ = this.morseChar$
.pipe(filter(this.isCharLongBreak as any));
// 切片成 Morse 单元组
this.morseSymbol$ = this.morseChar$
.pipe(
buffer(longBreaks$),
map(this.charArrayToSymbol),
filter(n => (n !== '') as any)
)
// 错误处理 + 标识符对应表转化
this.morseLetter$ = this.morseSymbol$
.pipe(
switchMap(n => observableOf(n).pipe(this.saveTranslate('ERROR')))
);
// Up 后补4个 “长间隔“ 标识符,用来做 Morse 单元组的结束
const breakEmitter$ = observableTimer(this.msLongBreak, this.msLongBreak)
.pipe(
mapTo(this.mC.longBreak),
take(4)
);
this.stopEventsSubject
.pipe(
switchMapTo(
breakEmitter$.pipe(takeUntil(this.startEventsSubject))
)
)
.subscribe(n => this.injectMorseChar(n));