是否有更简单的方法将MongoDB结果中的承诺链接起来?

时间:2016-06-06 10:36:25

标签: javascript node.js mongodb promise

此函数列出MongoDB数据库中的所有集合,其中包含每个集合中的文档数(bluebird承诺)。

function listMongoCollections(db) {
    var promises = []
    db.listCollections().toArray().then((docs) => {

        docs.forEach((doc) => {

            promises.push(
                new Promise((resolve) => {
                    db.collection(doc.name).count().then((count) => {
                        doc.count = count
                        resolve()
                    })
                })
            )
        })

        return Promise.all(promises)
    })
}

有更简单的方法吗?使用此方法将使代码充斥应用程序,我甚至没有包含错误处理。

1 个答案:

答案 0 :(得分:2)

你可以做一些事情:

  • 使用.map 集合数组转换为承诺数组,而不是手动.push进入数组。
  • 避免在新Promise中包装承诺。
  • 尽可能少地嵌套.then。在下面的示例中,请注意第一部分如何返回promises数组。只有在返回main函数之前,我们才将其包装在.all promise中。
function listMongoCollections(db) {
    const docs = db.listCollections().toArray().then(docs => {
        return docs.map(doc => {
            return db.collection(doc.name).count().then(count => {
                doc.count = count
                return doc;
            });
        });
    });
    return Promise.all(docs);
}

你可以简化"它还可以删除return和中间docs常量。

function listMongoCollections(db) {
    return Promise.all(
        db.listCollections().toArray().then(docs => 
            docs.map(doc => 
                db.collection(doc.name).count().then(count => {
                    doc.count = count
                    return doc;
                })
            )
        )
    );
}

也许使用async / await,我们可以让它更容易阅读(虽然我对它不太熟悉):

async function listMongoCollections(db) {
    let docs = await db.listCollections().toArray();
    docs = docs.map(async doc => {
        doc.count = await db.collection(doc.name).count();
        return doc;
    });
    return Promise.all(docs);
}

这些只是示例,Mongo可能会提供更好的解决方案。