如何链接Promises和回调式代码

时间:2018-03-07 23:54:07

标签: javascript promise return

我很担心这个承诺的链接是如何起作用的,我对承诺和js仍然相当新,所以请原谅我

第三行,return user.findOne({email}).then((user) => {,我只是对这个承诺如何做任何事情感到困惑,因为它在.then()中返回了另一个承诺

UserSchema.statics.findByCredentials = function(email, password){
  user = this;
  return user.findOne({email}).then((user) => {
      if (!user){
        return Promise.reject();
      }
      return new Promise((resolve, reject) => {
        bcrypt.compare(password, user.password, (err, res) => {
          if (res){
            resolve(user);
          }else{
            reject()
          }
        });
    });

  });
}

在快递应用中使用的findByCredentials模型方法

app.post("/users/login", (req, res) => {
  var body = _.pick(req.body, ["email", "password"]);
  User.findByCredentials(body.email, body.password).then((user) => {
    res.send(body)
  }).catch((e) => {
    res.send("!");
  })

我刚刚创建的一个更简单的例子,这部分

  

return plus(1).then((res)=> {

     
    

返回新的承诺((resolve,reject)=> {     是我无法理解的问题

  
function plus(a) {
  return new Promise((resolve, reject) => {
    resolve(a + 1);
  });
}

function test() {
  return plus(1).then((res) => {
    console.log(res);
    return new Promise((resolve, reject) => {
      resolve("Test");
    });
  });
}

test().then((res) => {
  console.log(res);
});

1 个答案:

答案 0 :(得分:4)

正如@Bergi在您的OP的评论中所说,真正的权力或Promises来自于其他then的{​​{1}}。

  • 这允许您以干净的方式链接 Promise。
  • 链接Promise链中的所有操作必须为Promises。
  • 您的Promises函数使用回调来表示已完成,因此您需要将该函数转换为bcrypt.compare

这很容易做到。只需将回调式代码包装在Promise中,并Promise回调的resolveresult,如果使用reject调用回调。

err

...然后我们可以正确链接:

const comparePassword = (a, b) => {
  return new Promise((resolve, reject) => {
    bcrypt.compare(a, b, (err, result) => {
      // Reject if there was an error
      // - rejection is `return`-ed solely for stopping further execution
      //   of this callback. No other reason for it.
      if (err) return reject(err)

      // Resolve if not.
      resolve(result)
    })
  })   
}

这里的关键是,UserSchema.statics.findByCredentials = function(email, password) { // Outer Promise: // - Will eventually resolve with whatever the result it's inner // promise resolves with. return user.findOne({ email }) .then((user) => { // Inner Promise: // - Will eventually resolve with `user` (which is already // available here), given that the password was correct, // or // reject with the bcrypt.compare `err` if the password was // incorrect. return comparePassword(password, user.password) .then((result) => { // This `then` belongs to the comparePassword Promise. // - We use this so we can make sure we return the `user` we picked up // from the previous `user.findOne` Promise. // - This ensures that when you chain a `then` to this Promise chain // you always get the `user` and not the result of `comparePassword` return user }) }) } 中的return将作为参数传递给下一个被链接的.then()

其他信息:

  • .then() already returns a Promise,所以我们可以避免把它包装成Promise的麻烦。我故意将它与回调一起用来说明你应该如何处理Promise链中的回调式代码。