我们正在尝试编写一个Google Cloud Function,该函数从Google Translate API获取翻译,然后将结果写入Firebase Firestore数据库。每个都单独起作用,但是一起没有效果。换句话说,我们可以从Google翻译获得翻译。我们可以将数据写入Firestore。但是,如果我们尝试同时执行这两项操作,则不会从Google Translate那里获得翻译,并且不会将任何内容写入Firebase。我们没有收到错误消息。我们已经使用async await
和Promise尝试了该代码。这是带有promise的代码:
exports.Google_EStranslateEN = functions.firestore.document('Users/{userID}/Spanish/Translation_Request').onUpdate((change, context) => {
if (change.after.data().word != undefined) {
const {Translate} = require('@google-cloud/translate');
const projectId = 'myProject-cd99d';
const translate = new Translate({
projectId: projectId,
});
// The text to translate
const text = change.after.data().word;
// The target language
const target = 'en';
let translationArray = []; // clear translation array
translate.translate(text, target)
.then(results => {
translation = results[0];
translationArray.push(translation);
try {
// write translation to dictionary
admin.firestore().collection('Dictionaries').doc('Spanish').collection('Words').doc(text).collection('Translations').doc('English').set({
'translationArray': translationArray,
'language': 'en',
'longLanguage': 'English'
})
.then(function() {
console.log("Translation written");
})
.catch(function(error) {
console.error(error);
});
} catch (error) {
console.error(error);
}
})
.catch(error => {
console.error('ERROR:', error);
});
}
});
这里与async await
的代码相同:
exports.Google_EStranslateEN = functions.firestore.document('Users/{userID}/Spanish/Translation_Request').onUpdate((change, context) => { // triggers when browser writes a request word to the database
if (change.after.data().word != undefined) {
async function getTranslation() {
try {
let translationArray = []; // clear translation array
const {Translate} = require('@google-cloud/translate');
const projectId = 'myProject-cd99d';
const translate = new Translate({
projectId: projectId,
});
// The text to translate
const text = change.after.data().word;
const options = {
to: 'en',
from: 'es',
format: 'text'
}
let [translations] = await translate.translate(text, options);
translations = Array.isArray(translations) ? translations : [translations]; // If translations is an array, leave it alone; if not, put it in an array
translationArray.push(translations[0]);
await admin.firestore().collection('Dictionaries').doc('Spanish').collection('Words').doc(text).collection('Translations').doc('English').set({
'translationArray': translationArray,
'language': 'en',
'longLanguage': 'English'
})
.then(function() {
console.log("Translation written");
})
.catch(function(error) {
console.error(error);
});
// };
} catch (error) {
console.error(error);
}
} // close getTranslation
getTranslation();
}
});
答案 0 :(得分:2)
所有异步工作完成后,您不会返回已解决的承诺。如果您不这样做,Cloud Functions会假设您的所有工作都已完成,并且将占用所有资源,并且所有待处理的工作都将被关闭。
translate.translate().then().catch()
返回的诺言被忽略。您对admin.firestore()...set()
的嵌套调用也有类似的问题。仅对每个诺言都调用then()
和catch()
是不够的,因为then()
和catch()
都返回了另一个诺言。
在promise上,您也不必要混合使用try / catch和catch()。您不需要这两种策略来进行错误处理,只需一种或另一种即可。
在第二个示例中使用await时,您迫使JavaScript暂停,直到set()
返回的promise表示的异步工作完成为止。这使您的函数仅在所有工作完成后才返回,这就是为什么它可以正常工作的原因。
观看我的video series在Cloud Functions中使用promise和async / await可能会对您有所帮助。正确处理诺言对于创建正确运行的功能至关重要。