首页 > 解决方案 > 由于 db-calls 在 Promise 中使用异步。如何修复此反模式?

问题描述

我有一个 Firebase 函数,它从数据库发回数据。问题是有时我必须返回所有 3 个集合的数据,有时只需要其中 1 个,有时需要 2 个。但这是一种反模式。如何改进我的代码?

现在我正在创建一个函数,它返回一个 Promise,我在其中使用 await 来获取 db 值,它包含在 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 块?

标签: javascriptfunctionfirebaseecmascript-6promise

解决方案


您可以改为使用该getList函数async,而不使用new Promisetry/ 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())
);

推荐阅读