ここでネクロマンサーをプレイします。それを行うための別のより良い方法がまだあるからです。
素晴らしい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)によってデータベースで見つかった記事
ご覧のとおり、インデントコールバックの地獄にさえ近づいていません。両方のデータベースクエリは並行して実行されます。一方が他方を待つ必要はありません。コードは短くて読みやすく、質問自体に投稿された希望に満ちた「機能しない例」に実質的に長さと複雑さ(またはむしろコードの欠如)が対応しています。
約束はかっこいいです。それらを使用してください。