嵌套的承诺和拒绝

法兰西斯科·文尼卡

我对promise函数有一些问题,我的应用程序具有以下结构:-路由-服务-数据库

db是在应用程序启动时初始化的类,我在其中为insert / find / ecc ...创建了一些包装函数。服务是路由和db之间的一层,在这里,我完成了大部分工作。我的问题是,使用下面的代码,如果用户已经存在,我想抛出一个错误或拒绝承诺,但是当我尝试做这样的事情时,我得到了

无法读取未定义的属性“ then”

错误在哪里?

这是我的资源:

router.put('/', (req, res, next) => {
  bcrypt.hash(req.body.password, 10)
    .then(function (hash) {
      req.body.password = hash;
      service.addUser(req.body)
        .then((user) => {
          return res.json(user);
        })
        .catch((err) => {
          return res.json(err);
        });
    })
    .catch((err) => {
      return res.json(err);
    });
});

这是服务:

  getBy(query) {
    return this.mongo.find(query);
  }

  addUser(data) {

    if(!data.email) {
      return Promise.reject('email_missing');
    }

    const self = this;
    self.getBy({ email: data.email })
      .then((user) => {
        if(user.length) {
          return Promise.reject('user_exist');
        }
        return self.mongo.insert(data)
      })
      .catch((err) => {
        return Promise.reject(err);
      });
  }

这是数据库连接:

  find(query) {
    const self = this;
    return new Promise((resolve, reject) => {
      self.collection.find(query).toArray((err, res) => {
        if (err) {
          self.logger.info('Mongo::find error', err);
          reject(err);
        } else {
          self.logger.info('Mongo::find', query);
          resolve(res);
        }
      });
    });
  }

  insert(data) {
    const self = this;
    return new Promise((resolve, reject) => {
      self.collection.insert(data, (err, res) => {
        if (err) {
          self.logger.info('Mongo::insert error', err);
          reject (err)
        } else {
          self.logger.info('Mongo::insert', res);
          resolve(res)
        }
      });
    });
  }

非常感谢!

addUser函数不返回Promise。该代码应如下所示:

addUser(data) {

  if (!data.email) {
    return Promise.reject('email_missing');
  }

  const self = this;
  return self.getBy({
      email: data.email
    })
    .then((user) => {
      if (user.length) {
        return Promise.reject('user_exist');
      }
      return self.mongo.insert(data)
    })
    .catch((err) => {
      return Promise.reject(err);
    });
}

.catch这里块是没有意义的,因为它仅包含它,return Promise.reject(err)因此您可以将其删除:

addUser(data) {

  if (!data.email) {
    return Promise.reject('email_missing');
  }

  const self = this;
  return self.getBy({
      email: data.email
    })
    .then((user) => {
      if (user.length) {
        return Promise.reject('user_exist');
      }
      return self.mongo.insert(data)
    });
}

在路由器中,您还必须在中返回Promise,.then然后可以删除一个.catch块:

router.put('/', (req, res, next) => {
  bcrypt.hash(req.body.password, 10)
    .then(function(hash) {
      req.body.password = hash;
      return service.addUser(req.body) // return the Promise ehre
    })
    // the then can be move out here, to avoid nesting
    .then((user) => {
      return res.json(user);
    })
    // only on catch is required
    .catch((err) => {
      return res.json(err);
    });
});

另外请注意,您应该始终拒绝出现实际错误。所以写会更好,Promise.reject(new Error('user_exist'))

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章