模特上的mongoose findOne会返回一个承诺吗?

Mat*_*tko 5 mongoose mongodb

我有一个简单的Node模块,它导出一个进行数据库查询的函数.问题是此函数在数据库查询完成之前返回.

"use strict";

var mongoose = require('mongoose'),
    Model    = require('./entities/user/model'),
    _        = require('underscore');

let dao = new Model(mongoose);

module.exports.isAdmin = function(user_id) {
  var params = {'roles': 'admin'};

  dao.findOne(params, function(err, user) {
    if (err) {
      logger.error(err);
      return false;
    }
    if (_.indexOf(user.roles, 'admin') != -1) {
      logger.info("admin user: " + user._id);
      if (user._id == user_id) return true;
    }
    return false;
  });
};
Run Code Online (Sandbox Code Playgroud)

isAdmin函数搜索用户集合以查明是否user_id属于admin用户.

问题是isAdmin函数不等待findOne查询的响应.

isAdmin如果查询返回结果,我怎么能强制函数返回?

zan*_*ngw 9

因为findOne异步函数,从中返回的一种方法是通过callback函数

module.exports.isAdmin = function(user_id, callback) {
  var params = {'roles': 'admin'};

  dao.findOne(params, function(err, user) {
    if (err) {
      logger.error(err);
      callback && callback(false);
    }
    if (_.indexOf(user.roles, 'admin') != -1) {
      logger.info("admin user: " + user._id);
      if (user._id == user_id)
          callback && callback(true);
    }
    callback && callback(true);
  });
};

isAdmin(userId, function(v) {
    console.log(v);
})
Run Code Online (Sandbox Code Playgroud)

另一种方法是让Promise进入findOne,正如这位医生所说,.exec()给你一个完全成熟的承诺.即使Promise满足您的要求,结果也可以通过回调函数返回.

module.exports.isAdmin = function(user_id, callback) {
  var params = {'roles': 'admin'};

  var queryPromise = dao.findOne(params).exec();
  queryPromise.then(function(user) {
      if (_.indexOf(user.roles, 'admin') != -1) {
        logger.info("admin user: " + user._id);
        if (user._id == user_id)
          callback && callback(true);
      }
    }, function(err) {
      callback && callback(false);
  });
};
Run Code Online (Sandbox Code Playgroud)

  • 你能详细说明"完全成熟的承诺"是什么吗? (2认同)
  • @HarleyAlexander,`完全成熟的承诺'与它定义的[Promise](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise)的功能相同,但是Mongoose查询不是承诺默认情况下.即使它们确实有`.then()`函数.如果您需要一个完全成熟的承诺,请在每个查询中使用`.exec()`.当您使用bluebird的`reflect()`函数等功能时,需要考虑这一点.您应该返回一个完整的承诺来使用此功能. (2认同)