2016-03-07 3 views
2

Я создаю CRUD api с выражением и mongodb. У меня есть конкретный маршрут, который запрашивает одну коллекцию в моем mongo db и извлекает все документы, соответствующие критериям запроса. Затем моя программа перебирает эти документы и пробует найти последнюю перекрестную запись в другой коллекции в моем дбПочему мое экспресс-приложение возвращает пустой массив?

exports.findLatestCommitforAllRepos = function(req,res,next){ 


var githubCommitDataCollection = index.db.collection(githubCommitDataCollectionName); 
var enabledRepoCollection = index.db.collection(enabledRepoCollectionName); 
var latestCommits = []; 

enabledRepoCollection.find({enabled:true}).toArray(function(err,repos) { 
    if (err) { next(err); } 
    if (repos.length === 0 || repos === 'undefined') { 
      res.status(404); 
      res.send("There are no repos being tracked") 
    } 
    else { 
     repos.forEach(function(enabledRepo) { 
      var repo = enabledRepo.repo; 
      var userOrOrg = enabledRepo.userOrOrg; 

      githubCommitDataCollection.find({repo: repo, userOrOrg:userOrOrg}).sort({commitDate: -1}).limit(1).toArray(function(err,commit) { 
       if (commit.length === 0 || repos === 'undefined') { 
        res.send("No commit found for repo " + repo); 
       } 
       // console.log(commit[0]); 
       latestCommits.push(commit[0]); 
       console.log(latestCommits); 

      }); 
     }); 
     res.setHeader('Content-Type', 'application/json');  
     res.status(200); 
     res.json(latestCommits); 
     res.end(); 
    } 

}); 
}   

Это приводит к пустому массиву возвращается.

+0

Это выглядит, как и его классический случай выдачи запроса асинхронной в цикле и ожидая все операции асинхронное быть сделано, когда цикл закончен, но ни один из них не имеют на самом деле закончен, поэтому ваша структура данных по-прежнему пуста. Вам нужно будет использовать что-то, что отслеживает ваши операции async, чтобы вы знали, когда все будет сделано. Это можно сделать с обещаниями, например, с асинхронной библиотекой или с вашими собственными счетчиками вручную. – jfriend00

+0

Вот примеры использования ручного счетчика: http://stackoverflow.com/questions/35760831/how-to-do-first-n-times-async-loops-then-one-time-function-in-callback- путь/35760975 # 35760975 и http://stackoverflow.com/questions/27119280/how-to-collect-the-value-to-an-array-in-nodejs-loop/27119344#27119344 и http: // stackoverflow. com/questions/29186700/node-js-callback-function-at-after-loop-has-end/29186825 # 29186825 и http://stackoverflow.com/questions/28122225/wait-for-several-db- connection-before-start-express-server/28122510 # 28122510 – jfriend00

+0

Вот примеры как решения для ручного счетчика, так и решения для обещаний: http://stackoverflow.com/questions/34808482/calling-a-function-having-callback- in-for-loop/34814720 # 34814720 и http://stackoverflow.com/questions/33815807/node-js-request-for-loop-runs-twice/33816588#33816588 – jfriend00

ответ

0

Вы можете использовать особенно метод async.waterfall() в async libary, когда вам нужно запустить массив задач функций в серии, каждая из которых проходит их результаты к следующему в массиве.

Рассмотрим следующий пример:

// Include the async package 
// Make sure you add "async" to your package.json 
async = require("async"); 

exports.findLatestCommitforAllRepos = function(req,res,next){ 
    var latestCommits = []; 
    async.waterfall([ 

     // Load all documents 
     function(callback) { 
      index.db.collection(enabledRepoCollectionName).find({"enabled": true}).toArray(function(err,repos){ 
       if (err) return callback(err);     
       callback(null, repos); 
      }); 
     }, 

     // Get count of documents where price is empty 
     function(reposData, callback) { 
      async.each(reposData, function(enabledRepo, callback) { 
       index.db.collection(githubCommitDataCollectionName) 
         .findOne({repo: enabledRepo.repo, userOrOrg: enabledRepo.userOrOrg}) 
         .sort({commitDate: -1}).limit(1) 
         .exec(function(err, commit) { 
          latestCommits.push(commit); 
          callback(); 
         }); 
      }, callback);    
     } 
    ], function(err, result) { //This function gets called after the three tasks have called their "task callbacks" 
     if (err) return next(err); 
     res.setHeader('Content-Type', 'application/json');  
     res.status(200); 
     res.json(latestCommits); 
     res.end(); 
    }); 
}); 
0

Одно небольшое предложение в коде, использование .findOne вместо .find

Средства вместо

githubCommitDataCollection.find({repo: repo, userOrOrg:userOrOrg}).sort({commitDate: -1}).limit(1).toArray(function(err,commit) { 

использования

githubCommitDataCollection.findOne({repo: repo, userOrOrg:userOrOrg}).sort({commitDate: -1}).exec(function(err,commit) { 

Он вернется только один фиксации и проверить console.log (commit), чтобы проверить, что вы получаете как результат.

Или Пожалуйста, проверьте долю существующих документов githubCommitDataCollection

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