Typescript массив обещаний, разрешающихся правильно в одном случае, но не в другом

Нет, в javascript нет возможности метапрограммирования, аналогично рубину method_missing. Интерпретатор просто вызывает ошибку, которую вызывающий код может уловить, но не может быть обнаружен объектом, к которому обращаются. Здесь есть некоторые ответы на определение функций во время выполнения, но это не одно и то же. Вы можете много метапрограммировать, изменять конкретные экземпляры объектов, определять функции, выполнять такие функциональные функции, как воспоминания и декораторы. Но нет динамического метапрограммирования отсутствующих функций, как в ruby ​​или python.

1
задан haudarren 18 March 2019 в 00:06
поделиться

3 ответа

Когда все электронные письма участников еще не существуют в документах, функции работают должным образом, и console.log () выводит идентификаторы итогового документа: hAvJ3qPq821tq1q2rrEv, 0tjeKB1aW8jsOAse5fcP

Это потому что он разрешает следующий оператор возврата:

return document_id;

Однако, когда хотя бы один адрес электронной почты связан с существующим документом, обещания addParticipant () не разрешаются ни к чему

Потому что не ничего не возвращает. Последнее ваше утверждение:

        // TODO: There is only one, so we shouldn't have to iterate
        querySnapshot.forEach(function(docRef: any) {
            console.log("New document id: " + docRef.id);
            const document_id = docRef.id;
            return document_id;
        });

Это , а не возврат любого идентификатора. Это просто forEach. Пример исправления будет выглядеть так:

        // Return the id
        return querySnapshot[0].document_id;
0
ответ дан basarat 18 March 2019 в 00:06
поделиться

Разобрался с некоторыми подсказками @basarat. Должен быть явный возврат для первого результата, а не цикл for: return querySnapshot.docs[0].id;. Полная измененная функция ниже:

async function addParticipant(email_address: string) {
    try {
        console.log("Querying for person");
        const query = await db.collection('people')
            .where('emails', 'array-contains', email_address)
            .limit(1);
        const querySnapshot = await query.get();
        if (!querySnapshot.empty) {
            console.log("Document exists for email " + email_address);
            return querySnapshot.docs[0].id;
        } else {
            console.log("Creating person with " + email_address);
            const fields = {emails: [email_address]};
            try {
                const docRef = await db.collection('people').add(fields);
                console.log("New document id: " + docRef.id);
                const document_id = docRef.id;
                return document_id;
            } catch (err) {
                console.log("Error adding document:", err);
            }
        }
    } catch (err) {
        console.log("Error getting document:", err);
    }
};
0
ответ дан haudarren 18 March 2019 в 00:06
поделиться

С Promise.all, если даже одно обещание не выполняется, вы не получите ни того, ни другого. Возьмите следующий пример:

const get = async () => {
    return Promise.all([
        new Promise((res, rej) => {
            setTimeout(() => {
                res('data!')
            }, 1000)
        }),
        new Promise((res, rej) => {
            setTimeout(() => {
                rej('error!')
            }, 2000)
        })
    ]);
}

const start = async () => {
    const response = await get()
    console.log(response)
}

start()

Вы просто получите ошибку Uncaught (in promise) error!.

Теперь, если вы хотите обойти это, чтобы получить хоть что-то обратно, вы можете потенциально использовать catch для каждого обещания, например, так:

const get = async () => {
    return Promise.all([
        new Promise((res, rej) => {
            setTimeout(() => {
                res('data!')
            }, 1000)
        }).catch(err => {
            return null
        }),
        new Promise((res, rej) => {
            setTimeout(() => {
                rej('error!')
            }, 2000)
        }).catch(err => {
            return null
        })
    ]);
}

const start = async () => {
    const response = await get()
    console.log(response)
}

start()

Это даст вам ["data!", null] и может обращаться с null, как вам удобно.

0
ответ дан Talha 18 March 2019 в 00:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: