2016-06-06 4 views
0

В этой функции перечислены все коллекции в базе данных MongoDB с количеством документов в каждой коллекции (bluebird).Есть ли более простой способ перевести обещания из результатов MongoDB?

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) 
    }) 
} 

Есть ли более простой способ сделать это? Используя этот метод, вы наполните приложение кодом, и я даже не включил обработку ошибок.

+0

Вы можете попробовать Q. Инструмент для создания и составления асинхронных обещаний в JavaScript http://documentup.com/kriskowal/q/ – Rudra

+0

Я не вижу, чтобы Q ничего не делал bluebird не может –

+1

@ PålThingbø в качестве источника как Q, так и Bluebird - я могу подтвердить это утверждение. –

ответ

2

Вы можете сделать несколько вещей:

  • использования .map для преобразования массива коллекций в массив обещаний, вместо того, чтобы .push ИНГОВ в массив вручную.
  • избегать обертывания обещаний в новых обещаниях.
  • гнездо .then как можно меньше. В следующем примере обратите внимание, как первая часть просто возвращает массив обещаний. Только перед возвращением основной функции мы завершаем ее в обещании .all.
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); 
} 

Это только примеры, Монго может предложить даже лучшие решения.

+3

Так как это обещания Bluebird, вы можете использовать ['.map()'] (http://bluebirdjs.com/docs/api/map.html) и ['.all()'] (http: // bluebirdjs .com/docs/api/all.html) (см. [this gist] (https://gist.github.com/robertklep/f8f558b0125c950722629d0b76e4dd49)). – robertklep

+1

Просто небольшая критика, которая является высокоразрешимой, но ИМО, оставляющая «возвращение», определенно не улучшает читаемость. С быстрым взглядом, как будто функции ничего не возвращают, пока вы не поймете, что фигурных скобок нет. Во всяком случае, это, вероятно, скорее критика синтаксиса толстой стрелки, чем ваше решение, но, возможно, вам следует добавить примечание о том, что функции обязательно должны вернуть обещания. – Creynders

+0

Полностью, вот почему я сказал и дважды цитировал _ «упростить» _, а не «улучшить читаемость». Идея Роберта в комментарии на самом деле является лучшим решением. –

Смежные вопросы