我正在开发一个将文本转换为莫尔斯电码音频的程序。
比如说我输入了 sos
。我的程序会把它转换成数组 [1, 1, 1, 0, 2, 2, 2, 0, 1, 1, 1]
。其中 s = 点 点 点
(或者 1,1,1
),o = 划 划 划
(或者 2,2,2
)。这部分很容易实现。
接下来,我有两个声音文件:
var dot = new Audio('dot.mp3');
var dash = new Audio('dash.mp3');
我的目标是要有一个函数,当它看到1
时播放dot.mp3
,当它看到2
时播放dash.mp3
,当它看到0
时暂停。
以下的代码有点儿用/类似/有时会有效,但我认为它基本上是有缺陷的,不知道该如何修复。
function playMorseArr(morseArr) {
for (let i = 0; i < morseArr.length; i++) {
setTimeout(function() {
if (morseArr[i] === 1) {
dot.play();
}
if (morseArr[i] === 2) {
dash.play();
}
}, 250*i);
}
}
问题:
我可以遍历数组并播放音频文件,但时间控制成为了一个挑战。如果我没有正确设置 setTimeout()
的间隔,当最后一个音频文件没有播放完且经过了 250ms
,下一个数组元素将被跳过。所以dash.mp3
比dot.mp3
长。如果我的时间控制太短,我可能会听到 [dot dot dot pause dash dash pause dot dot dot]
或类似的效果。
我想要的效果
我希望程序按以下方式运行(伪代码):
- 查看第
i
个数组元素 - 如果是
1
或2
,开始播放声音文件,否则创建暂停 - 等待声音文件或暂停完成
- 增加
i
并返回到步骤1
我所考虑的,但不知道如何实现的内容
因此,困难在于我想使循环同步进行。在我需要特定顺序执行多个函数的情况下,我使用过 promises,但是如何链接未知数量的函数?
我还考虑使用自定义事件,但我有同样的问题。