2015-08-21 2 views
0

Я уже назвал lean(), чтобы убедиться, что я преобразовал возвращенные данные в простой объект, но только истории [x] .authorId не добавляются как свойство к текущему объекту [x].Как изменить мои возвращенные данные из запроса Mongoose?

Может кто-нибудь объяснить, почему и обеспечить решение? Нужно ли это делать с областью видимости или что я не могу изменить объект в другом запросе?

Story.find({}).sort({created: -1}).lean().exec(function(err, stories) { 
    if (err) throw err; 
    for(var x=0; x < stories.length; x++) { 
     stories[x].commentsLength = stories[x].comments.length; 
     stories[x].created = stories[x]._id.getTimestamp(); 
     stories[x].timeAgo = timeHandler(stories[x]); 
     User.find({'username': stories[x].author}).lean().exec(function(x, err, data) { 
      stories[x].authorId = data[0]._id; 
       console.log(stories[x]); // authorId is there 
     }.bind(this, x)); 
     console.log(stories[x]); // authorId is not there 
    } 
    res.render('news', {message: "Homepage", data: stories}); 
}) 

ответ

0

Мне кажется, что вы пытаетесь выйти stories[x] после вызова асинхронного User.find() функции. Поскольку User.find() работает асинхронно, у вас не будет доступа к его результатам до тех пор, пока вызов не завершится. Другими словами, это ожидаемое поведение.

Что-то еще отметить, вы можете найти свой код легче читать, если вы используете функцию итератора как .forEach или даже async.each из модуля:

Story.find({}).sort({created: -1}).lean().exec(function(err, stories) { 
    if (err) throw err; 
    stories.forEach(function(story) { 
     story.commentsLength = story.comments.length; 
     story.created = story._id.getTimestamp(); 
     story.timeAgo = timeHandler(story); 
     User.find({ 
      'username': story.author 
     }).lean().exec(function(x, err, data) { 
      story.authorId = data[0]._id; 
      console.log(story); // authorId is there, because this means User.find completed 
     }.bind(this, x)); 
     console.log(story); // authorId is not there, and never will be, because this function executes before User.find completes its lookup 
    }); 
    res.render('news', { 
     message: "Homepage", 
     data: stories 
    }); 
}); 

Если вы пытаетесь изменить возвращение данных, вы можете использовать async для обеспечения выполнения всех функций поиска до завершения обратного вызова:

function getStory(callback) { 
    Story.find({}).sort({created: -1}).lean().exec(function(err, stories) { 
     if (err) throw err; 
     async.each(stories, function(story, callback) { 
      story.commentsLength = story.comments.length; 
      story.created = story._id.getTimestamp(); 
      story.timeAgo = timeHandler(story); 
      User.find({ 
       'username': story.author 
      }).lean().exec(function(x, err, data) { 
       story.authorId = data[0]._id; 
       callback(err, story); 
      }.bind(this, x)); 
     }, function(err, results) { 
      callback(err, results); // results is now an array of modified stories 
     }); 
     res.render('news', { 
      message: "Homepage", 
      data: stories 
     }); 
    }) 
} 
Смежные вопросы