问题
如何将async
辅助方法添加到Cloud Functions的index.js文件中?在将fs.writefile
转换为Promise时,需要async
函数才能使用await
,如StackOverflow文章中所述:fs.writeFile中的Promise异步同步内容。但是,lint不赞成在index.js文件中添加exports
函数之外的其他方法。
错误
行84指的是辅助函数async function writeFile
。
Users/adamhurwitz/converse/converse云函数/functions/index.js84:7错误分析错误:意外的令牌函数
✖1个问题(1个错误,0个警告)
npm ERR!代码ELIFECYCLE
npm ERR!错误1
npm ERR!函数@lint:
eslint .
npm ERR!退出状态1
npm ERR!
npm ERR!函数@lint脚本失败。
npm ERR!这可能不是npm的问题。上面可能有额外的日志输出。
npm ERR!此运行的完整日志可在以下位置找到:
npm ERR/用户/adamhurwitz/.npm/_logs/2018-12-12T01_47_50_684Z-debug.log
错误:函数预部署错误:命令终止,退出代码1 为非零
设置
index.js
const path = require('path');
const os = require('os');
const fs = require('fs');
const fsPromises = require('fs').promises;
const util = require('util');
const admin = require('firebase-admin');
const functions = require('firebase-functions');
const {Storage} = require('@google-cloud/storage');
const textToSpeech = require('@google-cloud/text-to-speech');
const storage = new Storage({
projectId: 'project-id',
});
const client = new textToSpeech.TextToSpeechClient();
admin.initializeApp();
exports.getAudiocast = functions.https.onCall((data, context) => {
const bucket = storage.bucket('gs://[bucket-name].appspot.com');
var fileName;
var tempFile;
var filePath;
return client.synthesizeSpeech({
input: {text: data.text },
voice: {languageCode: 'en-US', ssmlGender: 'NEUTRAL'},
audioConfig: {audioEncoding: 'MP3'},
})
.then(responses => {
var response = responses[0];
fileName = data.id + '.mp3'
tempFile = path.join(os.tmpdir(), fileName);
return writeFile(tempFile, response.audioContent)
})
.catch(err => {
console.error("Synthesize Speech Error: " + err);
})
.then(() => {
filePath = "filePath/" + fileName;
return bucket.upload(tempFile, { destination: filePath })
})
.catch(err => {
console.error("Write Temporary Audio File Error: " + err);
})
.then(() => {
return { filePath: filePath }
})
.catch(err => {
console.error('Upload Audio to GCS ERROR: ' + err);
});
});
助手方法:
async function writeFile(tempFile, audioContent) {
await fs.writeFile(tempFile, audioContent, 'binary');
}
尝试的解决方案
启用Node.js8,如Firebase Async Await样式的后云函数中所建议的。
设置Node.js版本
"engines": {"node": "8"}
return await fs.writeFile(tempFile, audioContent, 'binary');
Lint不喜欢这种解决方案。
我尝试了上面所有的解决方案,但都不适用。这是由于我的包.json:中的语法不好
"scripts": {
"lint": "eslint ."
},
更改为:
"scripts": {
"lint": "eslint"
},
就像Burak在评论中所说的那样,当我们创建firebase函数时,这个点是默认的
您的esint未配置为理解ECMAScript 2017语法。默认情况下,由Fire缺席CLI创建的.eslint.json配置文件包括以下配置:
"parserOptions": {
// Required for certain syntax usages
"ecmaVersion": 6
},
这样更改它以帮助它理解async/await:
"ecmaVersion": 2017
发布ES7您必须将其更改为ES8
2016年发布的ES7没有异步、等待或箭头功能您必须在.eslintrc上检查您是否至少有es8或2017,这是相同的。
如果文件是.eslintrc.json
"ecmaVersion":2017或"ecmaVersion":8
如果文件是.eslintrc.js
环境:{es8:true,节点:true}
对一些人来说,它是这样工作的
在我的案例中,它通过更改package.json来解决
"脚本":{"lint":"eslint"},
更改为:
"脚本":{"lint":"eslint"},
正如乔纳森所说,但我想知道为什么
a意识到我有两个名为的文件
- .eslintrc.js
- .eslintrc.json
这是eslintrc.json
和
这是eslintrc.json
正如您所看到的,在具有相同名称的两个文件中有不同版本的ecmaScript
- "ecmaVersion":2017//等于文件.eslintrc.json中的es8
- es6:true,//于2015年6月在文件.eslintrc.js中发布
所以当我们运行:npm-run lint时,它会运行带有es6:true的.eslintrc.js所以解决这个冲突只是删除.eslintrc.js,因为它有错误的ecmaScript。
如果您有.eslint.js
,只需将es6: true
更改为es2017: true
。
例如:
env: {
es6: true,
node: true,
},
变为:
env: {
es2017: true,
node: true,
},
更多详细信息,请参阅ESLint语言选项文档。
Node.js 8-Promisify
启用Node.js8,如Firebase Async Await样式的后云函数中所建议的。
- 设置Node.js版本
"engines": {"node": "8"}
-
使用
promisify
const writeFile = util.promisify(fs.writeFile);
return writeFile(tempFile, response.audioContent, 'binary')
Pre-Node.js 8-手动转换
这是一种将回调转换为承诺的旧方法,如本答案所述,该答案涉及有关谷歌文本到语音(TTS)的更具体的问题。
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!");
});
});
};
return writeFilePromise(tempFile, response.audioContent, 'binary');
更改.eslintrc.json 中的ecmaVersion
"parserOptions":{
//某些语法用法需要
"ecmaVersion":8
}
我遇到了同样的问题
我使用了与Firebase函数示例GitHub repo中的一个函数相同的ESLint配置。我在这里提到了这个特殊的例子:https://github.com/firebase/functions-samples/tree/main/child-count,它使用异步函数
我删除了eslintrc.js,并将其替换为与上述示例中相同的eslintrc.json文件。此外,在package.json中,添加了一个新的依赖项"eslint-plugin-promise": "^4.3.1"
,并删除了默认的"eslint-config-google": "^0.14.0"
(同样,与上面的示例一样)。
这似乎为我解决了问题。
.eslint.json
"parserOptions":{//某些语法用法需要"ecmaVersion":6.},这样更改它以帮助它理解async/await:
"ecmaVersion":2017年
package.json"脚本":{"lint":"eslint"},更改为:
"脚本":{"lint":"eslint";},
裁判Web队长和Doug Stevenson