54

マングースの結果でページをレンダリングするために私が見つけることができるすべては、次のようにそれを行うように言っています:

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

これはできますか?

4

6 に答える 6

67

同期パラダイムを強制しようとしています。ただ動作しません。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
});
于 2011-05-31T00:59:50.827 に答える
19

ここでネクロマンサーをプレイします。それを行うための別のより良い方法がまだあるからです。

素晴らしいpromiseライブラリ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);

すべてのマングース(およびそのモデル)メソッドを、Async接尾辞(.exec()になる.execAsync()など)を付けてpromiseを返す関数として使用できるようにします。.promisifyAll()このメソッドは、Node.JSの世界ではほぼ普遍的です。これは、コールバックを最後の引数として受け取る非同期関数を提供するあらゆるもので使用できます。

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

.props()bluebirdメソッドは、promiseをプロパティとして持つオブジェクトを受け取り、両方のデータベースクエリ(ここでは-promise)が結果を返すときに解決される集合的なpromiseを返します。解決された値はresults、最終関数のオブジェクトです。

  • results.users-マングースによってデータベースで見つかったユーザー
  • results.articles-マングース(d'uh)によってデータベースで見つかった記事

ご覧のとおり、インデントコールバックの地獄にさえ近づいていません。両方のデータベースクエリは並行して実行されます。一方が他方を待つ必要はありません。コードは短くて読みやすく、質問自体に投稿された希望に満ちた「機能しない例」に実質的に長さと複雑さ(またはむしろコードの欠如)が対応しています。

約束はかっこいいです。それらを使用してください。

于 2015-04-26T17:39:31.087 に答える
16

簡単な方法:

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では、実質的にすべての関数が非同期です。マングースの発見もそうです。また、シリアルに呼び出したい場合は、スライドライブラリのようなものを使用する必要があります。

しかし、あなたの場合、最も簡単な方法は、コールバックをネストするか(これにより、以前に選択したユーザーの記事を検索できるようにする)、非同期ライブラリを使用して完全に並行して実行することです(フロー制御/非同期グッズを参照)。

于 2011-05-31T00:49:51.020 に答える
1

ノード関数への戻りとしてかなり使用する関数があります。

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

次に、すべてのシグニチャにオプションのコールバックパラメータがあります。

于 2013-01-27T23:52:42.320 に答える
1

私は非常によく似たものを扱っていましたが、クライアントからのsocket.ioとDBアクセスを使用していました。私の発見は、データベースがデータを取得する前に、DBの内容をクライアントにスローバックすることでした...したがって、その価値について、ここで私の発見を共有します。

DBを取得するための私の関数:

//ボードの読み取り-完全な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);
        });
    });

したがって、問題を解決するために、マングースが私たちに与える約束を使用し、DBからデータを受信すると、私のソケットはそれをクライアントに返します...

その価値のために...

于 2013-04-23T10:32:59.253 に答える
1

次のコードで目的の結果を得ることができます。これがお役に立てば幸いです。

var async = require('async');

// custom imports
var User = require('../models/user');
var Article = require('../models/article');

var List1Objects = User.find({});
var List2Objects = Article.find({});
var resourcesStack = {
    usersList: List1Objects.exec.bind(List1Objects),
    articlesList: List2Objects.exec.bind(List2Objects),
};

async.parallel(resourcesStack, function (error, resultSet){
    if (error) {
        res.status(500).send(error);
        return;
    }
    res.render('home', resultSet);
});
于 2018-06-24T13:10:48.323 に答える