В настоящее время я использую amazon polly для создания звуковых файлов из данных, однако, когда я запускаю свой скрипт, я продолжаю получать сообщение об ошибке:
ThrottlingException: Rate exceeded.
Вот функция, которую я использую
function createAudioFiles(data, outputDir) {
console.info('in createAudioFiles with data: ' , data);
return new Promise((resolve, reject) => {
let successessfullyCompletedAmount = 0;
for ({ audioText, filename } of data) {
createAudio(audioText, filename, outputDir)
.then(({ status, message }) => {
if (status == "success") {
successessfullyCompletedAmount++;
console.info(message);
}
// if all audio files have been created
if (successessfullyCompletedAmount == data.length) {
resolve({
status: 'success',
message: "successfully created audioFiles"
})
}
})
}
});
}
Функция createAudio в этой функции:
function createAudio(text, filename, outputDir) {
let params = {
'Text': text,
'OutputFormat': 'mp3',
'VoiceId': 'Amy'
};
return new Promise((resolve, reject) => {
Polly.synthesizeSpeech(params, (err, data) => {
if (err) {
console.info("errors found");
console.info(err);
} else if (data) {
if (data.AudioStream instanceof Buffer) {
fs.writeFile(`${outputDir}/${filename}`, data.AudioStream, function (err) {
if (err) {
return reject({
status: "error",
message: err
})
}
resolve({
status: "success",
message: filename + " saved"
});
})
}
}
});
})
}.
Я попытался добавить оболочку setTimeout() в цикл for следующим образом:
setTimeout(function() {
for ({ audioText, filename } of data) {
createAudio(audioText, filename, outputDir)
.then(({ status, message }) => {
if (status == "success") {
successessfullyCompletedAmount++;
console.info(message);
}
// if all audio files have been created
if (successessfullyCompletedAmount == data.length) {
resolve({
status: 'success',
message: "successfully created audioFiles"
})
}
})
}
}, 2000);
но это, похоже, ничего не меняет. Я думаю, что все данные собираются и отправляются одновременно.
Я хотел бы добавить небольшую задержку между каждым получением от Amazon, чтобы замедлить скорость.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


чтобы добавить некоторую задержку между каждым вызовом createAudio, вы можете сделать что-то вроде этого:
return new Promise((resolve, reject) => {
let successessfullyCompletedAmount = 0;
let timeOutputDelay = 0;
for ({ audioText, filename } of data) {
setTimeout(function() {
createAudio(audioText, filename, outputDir)
.then(({ status, message }) => {
// [...]
})
} 1000 * timeOutputDelay);
timeOutputDelay++;
}
});
каждый setTimeout() будет иметь задержку в зависимости от того, сколько элементов уже зациклено.
Это решение не идеально, потому что вы не ждете, пока будет выполнено предыдущее поколение, прежде чем запускать следующее.
Таким образом, другой подход - связать все Promise.then с помощью:
С помощью этого подхода вы будете соединять каждый элемент вместе, и ваш код будет ждать конца текущего, прежде чем начинать следующий.
const createDummyAsyncPromise = (audio : {text: string, delay: number}) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(`Mp3 generated for text : ${audio.text}`);
}, audio.delay);
});
}
const audios = [
{text: 'text 1', delay: 2000},
{text: 'text 2', delay: 200},
{text: 'text 3', delay: 10},
{text: 'text 4', delay: 1000}
];
audios.reduce((promiseChain, audio) => {
return promiseChain.then(audioResults =>
createDummyAsyncPromise(audio).then(audioResult =>
[ ...audioResults, audioResult ]
)
);
}, Promise.resolve([])).then(audios => {
// Do something with all results
console.info(audios);
});
См. также Ограничение скорости очереди вызовов API и возврат результатов