Mongoose的JavaScript承诺

时间:2016-04-11 23:33:24

标签: javascript node.js mongodb

我在使用mongoose的promises注册一个尚未加入数据库的新用户时遇到了一些困难。这是我的代码:

exports.signup = (req) => {
  const newUser = {
    email: req.body.email,
    password: req.body.password
  };
  let result = {};
  return new Promise((resolve, reject) => {
    UserModel.findOne({email: newUser.email}, (err, existingUser) => {
      if (err) {
        return reject(err)
      } else {
        if (existingUser) {
          return reject()
        } else {
          result = newUser;
          UserModel.create(result);
          return resolve(result)
        }
      }
    })
  })
};

传入的请求值即将进入,但应用程序在finOne集合中断。

有人能发现错误吗?

非常感谢。

更新

如果省略mongoose方法:

exports.signup = (req) => {
  const newUser = {
    email: req.body.email,
    password: req.body.password
  };
  return Promise.resolve(newUser);
};

一切正常,但当然没有任何内容添加到数据库中。所以,我几乎可以理解,这与我的猫鼬方法有关。

最终更新:

我弄清楚我的错误是什么,但是pandres95打了我正确的答案,所以我给了他积分。但是我也会在下面提供我的解决方案,详细解释我搞砸了,以防其他人走同样的道路。

令人惊讶的是,积分低于10K的人总是能够拯救他们。 ;)

2 个答案:

答案 0 :(得分:1)

可能存在一些问题:

  1. 我注意到你没有使用回复(即res)。您使用的是哪个网络服务器库/框架?
  2. 然后,我更倾向于使用return作为退出语句来管理控制流,而不是一系列内联条件。它们可能会导致意想不到的结果。
  3. 在这种情况下,不建议使用result变量,因为:
    1. 作为范围变量,范围的变化可能是问题的一部分,
    2. 我觉得没必要,因为你曾经使用过一次。
  4. 以下是我从mongoose架构中解决相同情况的方法。

    var userSchema = new Schema({
        email: String,
        password: String
    });
    
    userSchema.statics.signup = function (data) {
        return new Promise((resolve, reject) => {
            this.findOne({
                email: data.email
            }, (err, existingUser) => {
                if(err) return reject(err);
                if(existingUser) return reject();
                return this.create(data, (err) => {
                    if(err) return reject(err);
                    return resolve(data);
                });
            });
        });
    };
    
    return userSchema;
    

    可以找到完整的解决方案(包括一些单元测试)here

答案 1 :(得分:1)

<强>解决方案:

犯了同样的错误,最终你学习了。 最初我有这个:

  

从&#39; ../ models / security / user.api.model&#39;;

导入UserModel

虽然正确,我的模型实际上将UserModel 显式声明为导出常量,这意味着我应该改为:

  

从&#39; ../ models / security / user.api.model&#39;;

导入{UserModel}

虽然具有挑战性,但我正在改进首发项目 react-redux-universal-hot-example

我正在使用静态网页端口 api端口拆分我的网站以获得更好的性能,我正在使用react-redux用于状态,同构/通用搜索引擎蜘蛛爬行的路由,这很重要,因为SPA(单页应用程序网站)不允许搜索引擎自动爬行。

不幸的是,上面提到的github项目没有提供db示例,所以我必须自己解决这个问题。

以下是使用JavaScript承诺的架构,api操作(服务器控制器)的示例解决方案:

<强> user.api.model.js:

'use strict';

import mongoose from 'mongoose';

const UserSchema = new mongoose.Schema({
  email: {type: String, required: '{PATH} is required!', index: {unique: true}},
  password: {type: String, min: 7, max: 15}, required: '{PATH} is required!',
  active: {type: Boolean, default: false},
  .....
  createdAt: { type: Date, default: Date.now() },
  updatedAt: { type: Date, default: Date.now() }
});



export const UserModel = mongoose.model('User', UserSchema);
带有承诺的

security.api.actions.js(控制器):

 'use strict';

import { UserModel } from '../../models/user/user.api.model';

.....

exports.signup = (req) => {
  let result = {};
  return new Promise((resolve, reject) => {
    UserModel.findOne({ email: req.body.email}, (err, existingUser) => {
      if (!existingUser) {
        const newUser = new UserModel({
           email: req.body.email,
           password: req.body.password
           ......
          });
        newUser.save((err) => {
            if (err) { 
              reject(err)
            } else {
              result = newUser;
            }
          });
      }
      if (err) reject(err);
      else resolve(result);
    })
  });
};

<强> auth.shared.reducer.js:

const LOAD = 'security/LOAD';
const LOAD_SUCCESS = 'security/LOAD_SUCCESS';
const LOAD_FAIL = 'security/LOAD_FAIL';
const LOGIN = 'security/LOGIN';
const LOGIN_SUCCESS = 'security/LOGIN_SUCCESS';
const LOGIN_FAIL = 'security/LOGIN_FAIL';
const LOGOUT = 'security/LOGOUT';
const LOGOUT_SUCCESS = 'security/LOGOUT_SUCCESS';
const LOGOUT_FAIL = 'security/LOGOUT_FAIL';
const SIGNUP = 'security/SIGNUP';
const SIGNUP_SUCCESS = 'security/SIGNUP_SUCCESS';
const SIGNUP_FAIL = 'security/SIGNUP_FAIL';
const initialState = {
  loaded: false
};

export default function reducer(state = initialState, action = {}) {
  switch (action.type) {
    case LOAD:
      return {
        ...state,
        loading: true
      };
    case LOAD_SUCCESS:
      return {
        ...state,
        loading: false,
        loaded: true,
        user: action.result
      };
    case LOAD_FAIL:
      return {
        ...state,
        loading: false,
        loaded: false,
        error: action.error
      };
    case LOGIN:
      return {
        ...state,
        loggingIn: true
      };
    case LOGIN_SUCCESS:
      return {
        ...state,
        loggingIn: false,
        user: action.result
      };
    case LOGIN_FAIL:
      return {
        ...state,
        loggingIn: false,
        user: null,
        loginError: action.error
      };
    case LOGOUT:
      return {
        ...state,
        loggingOut: true
      };
    case LOGOUT_SUCCESS:
      return {
        ...state,
        loggingOut: false,
        user: null
      };
    case LOGOUT_FAIL:
      return {
        ...state,
        loggingOut: false,
        logoutError: action.error
      };
    case SIGNUP:
      return {
        ...state,
        signingUp: true
      };
    case SIGNUP_SUCCESS:
      return {
        ...state,
        signingUp: false,
        user: action.result
      };
    case SIGNUP_FAIL:
      return {
        ...state,
        signingUp: false,
        user: null,
        signUpError: action.error
      };
    default:
      return state;
  }
}
export function isLoaded(globalState) {
  return globalState.auth && globalState.auth.loaded;
}

export function load() {
  return {
    types: [LOAD, LOAD_SUCCESS, LOAD_FAIL],
    promise: (client) => client.get('/security/createUserSession')
  };
}

export function login(name) {
  return {
    types: [LOGIN, LOGIN_SUCCESS, LOGIN_FAIL],
    promise: (client) => client.post('/security/login', {
      data: {
        name
      }
    })
  };
}

export function logout() {
  return {
    types: [LOGOUT, LOGOUT_SUCCESS, LOGOUT_FAIL],
    promise: (client) => client.get('/security/logout')
  };
}

export function signup(email, password) {
  return {
    types: [SIGNUP, SIGNUP_SUCCESS, SIGNUP_FAIL],
    promise: (client) => client.post('/security/signup', {
      data: {
        email: email,
        password: password
      }
    })
  };
}

如果您是React编码器或发烧友,我建议您查看该入门套件(如果您还没有)。这是最前沿的,但我相信所采用的技术将在不久的将来成为标准。