Подтвердить что ты не робот

Как вернуть результаты Mongoose из метода поиска?

Все, что я могу найти, чтобы разбить страницу с результатами мангуста, говорит, чтобы сделать это следующим образом:

users.find({}, function(err, docs){
    res.render('profile/profile', {
        users:     docs
    });
});

Как я могу вернуть результаты запроса, более того?

var a_users = users.find({}); //non-working example

Чтобы я мог опубликовать несколько публикаций на странице?

как:

/* non working example */
var a_users    = users.find({});
var a_articles = articles.find({});

res.render('profile/profile', {
      users:    a_users
    , articles: a_articles
});

Можно ли это сделать?

4b9b3361

Ответ 1

Вы пытаетесь заставить синхронную парадигму. Просто не работает. node.js является однопоточным, по большей части - при выполнении io выполняется контекст выполнения. Сигнализация управляется обратным вызовом. Это означает, что вы либо имеете вложенные обратные вызовы, именованные функции, либо библиотеку управления потоком, чтобы сделать вещи более привлекательными.

https://github.com/caolan/async#parallel

async.parallel([
   function(cb){
      users.find({}, cb);
   },
   function(cb){
      articles.find({}, cb);
   }
], function(results){
   // results contains both users and articles
});

Ответ 2

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

Используя замечательную библиотеку обещаний Bluebird и ее метод promisifyAll():

var Promise = require('bluebird');
var mongoose = require('mongoose');

Promise.promisifyAll(mongoose); // key part - promisification

var users, articles; // load mongoose models "users" and "articles" here

Promise.props({
    users: users.find().execAsync(),
    articles: articles.find().execAsync()
  })
  .then(function(results) {
    res.render('profile/profile', results);
  })
  .catch(function(err) {
    res.send(500); // oops - we're even handling errors!
  });

Ключевые части:

Promise.promisifyAll(mongoose);

Использует все методы мангуста (и его модели) как функции, возвращающие promises, с суффиксом Async (.exec() становится .execAsync() и т.д.). .promisifyAll() метод почти универсален в мире Node.JS - вы можете использовать его для чего-либо, предоставляя асинхронные функции, принимающие обратный вызов в качестве их последнего аргумента.

Promise.props({
    users: users.find().execAsync(),
    articles: articles.find().execAsync()
  })

.props() метод bluebird принимает объект с promises в качестве своих свойств и возвращает коллективные обещания, которые решаются, когда оба запроса базы данных (здесь - promises ) возвращают свои результаты. Решенное значение - наш results объект в конечной функции:

  • results.users - пользователи, находящиеся в базе данных mongoose
  • results.articles - статьи, найденные в базе данных mongoose (d'uh)

Как вы можете видеть, мы даже не приближаемся к аддону. Оба запроса базы данных выполняются параллельно - нет необходимости, чтобы один из них ожидал другого. Код короткий и читаемый - практически соответствующий по длине и сложности (или, скорее, недостаток) желаемого "нерабочего примера", размещенного в самом вопросе.

Promises являются классными. Используйте их.

Ответ 3

Простой способ:

var userModel = mongoose.model('users');
var articleModel = mongoose.model('articles');
userModel.find({}, function (err, db_users) {
  if(err) {/*error!!!*/}
  articleModel.find({}, function (err, db_articles) {
    if(err) {/*error!!!*/}
    res.render('profile/profile', {
       users: db_users,
       articles: db_articles
    });
  });
});

Практически каждая функция асинхронна в Node.js. Так что найти Мангуста. И если вы хотите называть это серийно, вы должны использовать что-то вроде Slide.

Но в вашем случае я думаю, что самый простой способ - установить ответные вызовы (это позволяет создавать статьи для выбранных ранее пользователей) или сделать это полностью параллельно с помощью асинхронных библиотек (см. Управление потоком/асинхронные лакомства).

Ответ 4

У меня есть функция, которую я использую совсем немного как возврат к функциям Node.

function freturn (value, callback){
    if(callback){
        return callback(value); 
    }
    return value; 
}; 

Затем у меня есть необязательный параметр обратного вызова во всех подписях.

Ответ 5

Я имел дело с очень похожими вещами, но с помощью доступа socket.io и DB к клиенту. Моя находка бросала содержимое моего БД обратно клиенту, прежде чем база данных имела возможность получить данные... Итак, для чего это стоит, я поделюсь своими выводами здесь:

Моя функция для извлечения БД:

//Чтение плат - полная БД

var readBoards = function() {
        var callback = function() {
            return function(error, data) {
                if(error) {
                    console.log("Error: " + error);
                }
                console.log("Boards from Server (fct): " + data);

            }
        };

        return boards.find({}, callback());
    };

Мой прослушиватель событий сокета:

socket.on('getBoards', function() {
        var query = dbConnection.readBoards();
        var promise = query.exec();
        promise.addBack(function (err, boards) {
            if(err)
                console.log("Error: " + err);
            socket.emit('onGetBoards', boards);
        });
    });

Итак, чтобы решить проблему, мы используем обещание, которое дает нам мангуста, а затем, как только мы получили данные из БД, мой сокет выдает его обратно клиенту...

За что его стоит...