Возврат после цикла forEach фактически возвращается перед ним (узел)

#javascript #node.js #google-cloud-firestore #google-cloud-functions

#javascript #node.js #google-облако-firestore #google-cloud-функции

Вопрос:

У меня есть облачная функция Google, с помощью которой мне нужно просмотреть серию документов firestore, а затем выполнить проверку определенного поля. Как только проверка выполнена, это добавляет это поле к объекту, который я назвал item. Как только это будет сделано, у меня появится .then() функция, которая объединяет элемент в документ.

Проблема в том, что этот возврат в цикле forEach возвращается ПОСЛЕ этого окончательного возврата, что означает, что элемент добавляется в документ без обязательных полей.

Я полагаю, что проблема может быть в Promises , хотя я не уверен.

Вот моя функция:

 function updateReferenceToComplete(refDoc: any, contract_type: string, contract_pdf: string, guarantorData: any, custom_fields: any) {
    let item: any;

    return refDoc.get()
        .then((data: any) => {
            const reference = data.data();

                item = {
                    date_modified: new Date(),
                    date_signed: new Date(),
                    tenancy_offers: {},
                    status: 'complete',
                    agreement_url: contract_pdf,
                    custom_fields: custom_fields,
                };


             Object.keys(reference.tenancy_offers).forEach((key: string) => {
                console.log('KEYS: ', key);
                if (isNull(reference.tenancy_offers[key])) {

                    const offerDoc = db.collection('tenancy_offers').doc(key);

                    return offerDoc.get()
                       .then((offerData: any) => {
                           const offer = offerData.data();
                            if (offer.status === 'incomplete' amp;amp; !offer.is_deleted) {

                                item.tenancy_offers[key] = new Date();
                                console.log('ITEM IN FOR EACH: ', item);
                            } else {
                                item.tenancy_offers[key] = null;
                            }
                       })
                } else {
                    return null
                }
            });

        }).then(() => {
            console.log('ITEM AFTER LOOP: ', item);
            return refDoc.set(item, {merge: true})
                .then(() => console.log('done'))
                .catch((err: any) => console.log(err))
        })
} 
  

Итак, как вы можете видеть, я консольный элемент журнала во время цикла и после цикла, но журнал «ПОСЛЕ» цикла регистрируется первым, что означает, что tenancy_offer объект остается пустым в firestore.

Ответ №1:

offerDoc.get().then() является асинхронным и возвращает обещание. Использование then() не заставляет ваш код останавливаться и ждать разрешения обещания — оно просто возвращает другое обещание. Возможно, вы хотите собрать эти обещания в массив и использовать Promise.all() , чтобы дождаться их завершения, прежде чем переходить к следующему этапу.