(Ответ отредактирован в ответ на редактирование вопроса ...)
В исходном вопросе вы вызвали
client.synthesizeSpeech(request, (err, response) => {...})
по шаблону обратного вызова http
узла, в котором используется функция обратного вызоваможет инициировать до завершения ответа.Ваш последующий код вызывает методы, которые предполагают содержание ответа;если ответ по-прежнему пуст, fs.writeFile()
изначально ничего не записывает, а последующие методы не могут найти несуществующий файл.(Поскольку fs.writeFile()
следует той же схеме обратного вызова, вы можете даже обнаружить, что файл output.mp3
после выхода из программы, потому что fs
будет передавать поток данных. Но я уверен, что ваши методы Firebase не ждут.)
Решение - использовать Promises или async / await.Глядя на Google TextToSpeechClient
класс документов , похоже, что метод synthesizeSpeech
поддерживает это:
Возвращает: Promise -> Array.Первым элементом массива является объект, представляющий SynthesizeSpeechResponse.
Пример:
client.synthesizeSpeech(request)
.then(responses => {
var response = responses[0];
// doThingsWith(response)
})
.catch(err => {
console.error(err);
});
Это должно решить проблему с client.synthesizeSpeech
, но, к сожалению, fs.writeFile
по-прежнему синхронно,Если бы вы использовали Node> 10, вы могли бы использовать собственный метод fsPromise.writeFile
, а если бы вы использовали Node> 8, вы могли бы использовать util.promisify()
для преобразования fs.writeFile
в обещания.Но вы указали в комментариях, что используете Node 6, поэтому нам придется делать все вручную.Отбросив от эту ссылку :
const writeFilePromise = (file, data, option) => {
return new Promise((resolve, reject) => {
fs.writeFile(file, data, option, error => {
if (error) reject(error);
resolve("File created! Time for the next step!");
});
});
};
client.synthesizeSpeech(request)
.then(responses => {
const response = responses[0];
return writeFilePromise(tmpFilePath, response.audioContent, 'binary');
})
.then(() => {
return gcs.bucket(fileBucket).upload(tmpFilePath, {
destination: join(bucketDir, pageName)
});
})
.then(() => {
console.log('audio uploaded successfully');
return null;
})
.catch((error) => { console.log(error) });
Я написал все это, используя .then
конструкции, но, естественно, вы также можете использовать async
/ await
, если хотитескорее сделай это.Я надеюсь, что это все исправит - это заставит ваш код Firebase ждать, пока fs.writeFile
не завершит свою работу.Я также, к сожалению, перенес все проверки ошибок в один последний .catch
блок.И сделал вещи немного многословными для ясности.Я уверен, что вы можете сделать лучше.