简体   繁体   English

Node JS承诺链

[英]Node JS promise chaining

I am trying to chain a few promises in Node.js, but am only used to jQuery promises. 我试图在Node.js中链接一些Promise,但仅用于jQuery Promise。 The problem I am having is my higher level function (registerUser) that chains the promises does not seem to fail (go in to the catch handler) when the bcrypt hash fails (I change the code to set the string to null as a test). 我遇到的问题是,当bcrypt哈希失败时(我将代码更改为将字符串设置为null进行测试),我的上层函数(registerUser)链接诺言似乎没有失败(进入catch处理程序) 。

What I want to accomplish is 我要完成的是

  1. A hash function that returns a promise, and logs its own failure 散列函数,返回一个promise,并记录其自身的失败

  2. An insert function that returns a promise, and logs its own failure 一个插入函数,返回一个promise,并记录其自身的失败

  3. A register function that calls the hash, then the insert, and logs either failures 一个注册函数,调用该哈希,然后插入,并记录其中一个失败

This is my code. 这是我的代码。

hashPassword(password){
    let self = this;
    // if you set password to null, the catch err is printed.
    // but in registerUser, .then() is still called...
    return bcrypt.hash(password, 10)
        .then(function(hash) {
            return hash;
        })
        .catch(function(err){
            self.logger.error('failed to hash password');
        });
}

insertUser(email, passwordHash){
    let self = this;
    let data = {
        email: email,
        password: passwordHash
    };
    return this.collection.insertOne(data)
        .then(function(res) {
            self.logger.info(`user ${email} registered`);
        })
        .catch(function(err){
            self.logger.error('failed to add user to db');
        });
}

registerUser(email, password){
    let self = this;
    return this.hashPassword(password)
        .then(function(hash){
            // is this returning the promise of 
            // insertUser to the caller of registerUser?
            return self.insertUser(email, hash);
        })
        // which promise am i catching here?
        .catch(function(){
            self.logger.error('failed to register user');
        });
}

Finally someone calls the register function and should know if it was successful. 最后,有人调用了寄存器函数,应该知道它是否成功。

let user = new User();
user.registerUser('a@b.com', '1234')
   .then(function(){
       res.sendStatus(200);
   })
   .catch(function(){
      res.sendStatus(400);
   });

I think I've realized I was expecting then to be a success handler, but it is also an error handler. 我想,我已经意识到我期待then是成功的处理程序,但它也是一个error处理程序。 This kinda sucks. 有点烂 Is there a success only handler? 有成功的唯一处理程序吗?

catch deals with errors, so if you catch an error in doesn't propagate down the line. catch处理错误,因此,如果您捕获错误,则不会传播。 If you want that error to continue to a catch block further down you need to return a rejected promise from catch . 如果您希望该错误继续到下一个catch块,则需要从catch返回一个被拒绝的promise。 Something like: 就像是:

hashPassword(password){
    let self = this;
    // if you set password to null, the catch err is printed.
    // but in registerUser, .then() is still called...
    return bcrypt.hash(password, 10)
        .then(function(hash) {
            return hash;
        })
        .catch(function(err){
            self.logger.error('failed to hash password');
            // Pass on the error
            return Promise.reject('failed to hash password')
        });
}

You'll need to do this for any catch for which you only want side effects, but don't want to actually "catch" the error. 您需要对仅需要副作用但不希望真正“捕获”错误的任何catch执行此操作。

Create the function so they return promises 创建函数,以便他们返回承诺

    createHash(email, password){
        let self = this;
        return this.hashPassword(password);            
    }

First create the hash and use then on the returned promise, In the then handler return create user and return another promise and use another then on it to send the response after the creation of the user. 首先创建哈希值,然后对返回的promise使用,然后在处理程序中返回create user,然后返回另一个promise,并在用户创建后使用另一个promise发送响应。 If any error occur the catch will fire returning 400. 如果发生任何错误,则捕获将返回400。

    let user = new User();
    user.createHash('a@b.com', '1234')
      .then(function(hash){
          return self.insertUser(email, hash);              
      })
      .then((user) => res.sendStatus(200))
      .catch(function(error){
         res.sendStatus(400);
      });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM