Использование async в обещании из-за db-вызовов.Как я могу исправить этот антипаттерн? - PullRequest
0 голосов
/ 04 февраля 2019

У меня есть функция Firebase, которая отправляет данные из баз данных.Проблема в том, что иногда мне приходится возвращать данные всех 3 коллекций, иногда нужно только 1, а иногда 2 из них.Но это антипаттерн.Как я могу улучшить свой код?

Сейчас я создаю функцию, которая возвращает обещание, в котором я использую await для получения значений в БД, и это заключено в блок try {}.

module.exports.getList = (uid, listType) => new Promise(async (resolve, reject) => {
let returnValue = [];
try {
    if (listType.contains("a")) {
        const block = await db.collection('alist').doc(uid).get();
        returnValue.push(block);
    }
    if (listType.contains("b")) {
        const like = await db.collection('blist').doc(uid).get();
        returnValue.push(like);
    }
    if (listType.contains("c")) {
        const match = await db.collection('clist').doc(uid).get();
        returnValue.push(match);
    }
} catch (e) {
    return reject(e);
}
return resolve(returnValue);});

Как мне изменить этот фрагмент, чтобы не быть антипаттерном?Или это не из-за блока try-catch?

1 Ответ

0 голосов
/ 04 февраля 2019

Вместо этого вы можете сделать getList функцию async, без new Promise или try / catch:

module.exports.getList = async (uid, listType) => {
  const returnValue = [];
  if (listType.contains("a")) {
    const block = await db.collection('alist').doc(uid).get();
    returnValue.push(block);
  }
  if (listType.contains("b")) {
    const like = await db.collection('blist').doc(uid).get();
    returnValue.push(like);
  }
  if (listType.contains("c")) {
    const match = await db.collection('clist').doc(uid).get();
    returnValue.push(match);
  }
  return returnValue;
};

Вызов ее вернет Promise, который отклоняется сошибка, если есть асинхронная ошибка, или она преобразуется в нужный массив.

Обратите внимание, что, если нет веской причины await каждый вызов в последовательном режиме, вы можете использовать Promise.all вместо этого, чтобы запросывыйдите параллельно и сделайте код намного более лаконичным в процессе:

module.exports.getList = (uid, listType) => Promise.all(
  ['alist', 'blist', 'clist']
    .filter(name => listType.contains(name[0]))
    .map(name => db.collection(name).doc(uid).get())
);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...