Mongoose で完全なる ES6 Promise を使う

現行の Mongoose 4.2.4 ではネイティブ Promise がサポートされていない。Query オブジェクトの exec メソッドを引数無しで呼び出すと、Mongoose 独自の Promise が返るがチェインの中で利用すると上手く動かなかった。

http://mongoosejs.com/docs/api.html#promise_Promise

リンク先に Mongoose 5.0 でネイティブ Promise がサポートされるとあるが今使いたい。そこで Query オブジェクトに execPromise メソッドを拡張実装してみる。

var mongoose = require('mongoose');

mongoose.Query.prototype.execPromise = function() {
  var self = this;
  return new Promise(function(resolve, reject){
      self.exec(function(err, data){
        if (err) reject(err);
        else resolve(data);
      });
    });
}

以下のようにチェインで使うことができる。

// fetch an author who writes an article
var promise = Article.find({ id: 1 }).execPromise();

promise.then(function(article){
  return Author.find({ id: article.author }).exePromise();
})
.then(function(author){
  console.log(author);
})
.catch(function(err){
  console.log(err);
});