# #firebase #google-cloud-firestore #promise #google-cloud-functions
Вопрос:
Я пишу функции Firebase Could с помощью машинописного текста, и ниже приведен простой способ обновления документа.
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
admin.initializeApp(functions.config().firebase);
export const handleTestData = functions.firestore.document('test/{docID}').onCreate(async (snap, context) => {
const data = snap.data();
if (data) {
try {
await admin.firestore().doc('test1/' context.params.docID '/').update({duplicate : true});
} catch (error) {}
}
});
В этом методе обещание обрабатывается, async
await
и нет никакого return
утверждения, и оно работает нормально. В большинстве примеров/учебных пособий, которые я видел return
, в каждом методе всегда есть оператор.
Есть ли какое-либо влияние/разница, что я ничего не возвращаю в облачных функциях Firebase? Если я должен что-то вернуть, могу ли я вернуться null
?
Ответ №1:
Важно ли возвращаемое значение в облачных функциях Firebase?
Да, это действительно ключевой момент в облачной функции, которая выполняет асинхронную обработку (также известную как «фоновые функции»), чтобы вернуть обещание JavaScript, когда вся асинхронная обработка завершена, как описано в документации.
Это важно по двум основным причинам (выдержки из документа).:
- Вы убедитесь, что экземпляр Облачных функций, на котором выполняется ваша Облачная функция, не завершит работу до того, как ваша функция успешно достигнет своего завершающего состояния или состояния.
- Вы можете избежать чрезмерных сборов с облачных функций, которые выполняются слишком долго или бесконечно.
Почему ваша облачная функция работает правильно, даже если вы не возвращаете обещание?
Обычно ваша Облачная функция должна быть завершена до завершения асинхронных операций, поскольку вы не возвращаете обещание и, следовательно, указываете платформе Облачных функций, что она может завершить экземпляр Облачных функций, выполняющий Облачную функцию.
Но иногда платформа облачных функций не завершает функцию немедленно, и асинхронные операции могут быть завершены. Это совсем не гарантировано и полностью выходит из-под вашего контроля.
Опыт показал, что для коротких асинхронных операций этот последний случай происходит довольно часто, и разработчик думает, что все в порядке. Но внезапно, в один прекрасный день, Облачная функция не работает… и иногда она действительно работает: разработчик сталкивается с «неустойчивым» поведением без какой-либо четкой логики, что очень затрудняет отладку. В разделе Переполнение стека вы найдете множество вопросов, иллюстрирующих эту ситуацию.
Таким образом, конкретно в вашем случае вы можете адаптировать свой код следующим образом:
export const handleTestData = functions.firestore.document('test/{docID}').onCreate(async (snap, context) => {
const data = snap.data();
if (data) {
try {
// See the return below: we return the Promise returned by update()
return admin.firestore().doc('test1/' context.params.docID '/').update({duplicate : true});
} catch (error) {
return null; // <- See the return
}
} else {
return null; // <- See the return
}
});
или как
export const handleTestData = functions.firestore.document('test/{docID}').onCreate(async (snap, context) => {
const data = snap.data();
if (data) {
try {
await admin.firestore().doc('test1/' context.params.docID '/').update({duplicate : true});
return null; // <- See the return
} catch (error) {
return null; // <- See the return
}
} else {
return null; // <- See the return
}
});
Возврат null
(или true
, или 1
…) допустим, так async
как функция всегда возвращает обещание.
Комментарии:
1. Привет @Renaud, большое спасибо за объяснение. Один вопрос. У меня есть несколько более крупных функций с множеством ветвей для завершения функции. Могу ли я просто вернуть значение null один раз в конце функции вместо того, чтобы возвращать его во всех ветвях? Например, вы возвращаете значение null в 3 местах в примере кода. Будет ли это то же самое, что возвращать значение null в конце функции. Потому что, если
if(data)
это не удастся, это также должно вернуть обещание.2. Да, поскольку вы используете
async/await
, вы можете написать свой код аналогично синхронному коду. Если бы вы использовалиthen()
вместоasync/await
этого, вам пришлось бы позаботиться о том, чтобы не звонитьreturn
до завершения асинхронной работы.