速记承诺链

时间:2018-10-16 21:09:50

标签: javascript node.js promise

我正在尝试自学节点并进行表达,并试图构建一个简单的登录脚本。我是Java语言承诺的新手。

我的用户模型具有existsverifiyPasswordisApproved之类的功能。每个函数如下所示:

//Simplified verifyPassword function
User.prototype.verifyPassword=function(suppliedPassword){
    return new Promise((resolve,reject)=>{
        if(suppliedPassword === this.password){
            return resolve(true);
        }
        return reject(new Error('Password incorrect'));
    })
}

我想像这样将一系列方法链接在一起(注意:我正在使用 WRONG 密码进行测试)

第一次尝试:

 user.exists()
.then(user.verifyPassword(req.body.password)).
.then(user.isApproved())
.then(()=>{
     console.log("Login successful");
}).catch(err=>{
      console.log("ERROR", err);
      throw err
});

结果:UnhandledPromiseRejectionWarning: Error: Password incorrect Login successful

显然是错误的结果(未发现错误,但仍然可以成功登录)。我相信这是因为user.verifyPassword()没有兑现承诺。

第二次尝试:

 user.exists()
.then(user.verifyPassword.bind(req.body.password)).
.then(user.isApproved)
.then(()=>{
     console.log("Login successful");
})

我认为这可能有效,但是没有将req.body.password传递给verifyPassword(相反,它传递了true解决的结果user.exists())。

第三次尝试:

 user.exists()
.then(()=>{return user.verifyPassword.bind(req.body.password)}).
.then(()=>{return user.isApproved})
.then(()=>{
     console.log("Login successful");
})

此代码可以正常工作,但感觉很冗长。有什么办法可以清理吗?我对ES6速记技巧还不太熟悉。

2 个答案:

答案 0 :(得分:1)

确保您可以缩短代码,但首先,对诺言有一些误解。最后,我给您一个解决方案和另一个简短版本。但是我建议您在使用该代码之前,真正地尝试并详细了解Promise。这是javascript的重要组成部分。

https://www.datchley.name/es6-promises/

https://www.datchley.name/promise-patterns-anti-patterns/


1。试试

us_map <- fortify(us, region="name")

ggplot() +
  geom_map(
    data = us_map, map = us_map,
    aes(x = long, y = lat, map_id = id),
    color = "#2b2b2b", size = 0.1, fill = NA
  ) +
  geom_point(
    data = states_centers, aes(x, y), size = 4, color = "steelblue"
  ) +
  coord_equal() + # the points are pre-projected
  ggthemes::theme_map()

then 应该具有功能。但是,您传递的是Promise对象的verifyPassword的结果。您的表达式将变成.then(user.verifyPassword(req.body.password)) ,以便then(null)的先前结果通过。

相反,您可以执行以下操作:

user.exists()

2。试试

  

显然是错误的结果(未发现错误,但仍然会   成功登录)。我相信这是因为user.verifyPassword()是   没有兑现承诺。

看看bind的函数签名:

`function.bind(thisArg [,arg1 [,arg2 [,...]]])``

因此,您正在传递 req.body.password 作为thisArg。它被忽略,因为用户是从new入手的。 但是,现在没有 arg1 ,因此 suppliedPassword 是未定义的。

相反,您会这样做:

user.exists()
.then(() => user.verifyPassword(req.body.password))

3。试试

您未在此处调用verifyPassword并已批准。因此,尝试这样:

user.verifyPassword.bind(null, req.body.password)

或更短:

.then(()=>{return user.isApproved()})

解决方案

.then( () => user.isApproved() )

更短的解决方案

如果要使我们使用更短的语法,可以使用async / await。 This youtube video可能会为您提供帮助。

 user.exists()
  .then(() => user.verifyPassword(req.body.password))
  .then(user.isApproved)
  .then(()=>{
     console.log("Login successful");
  }).catch(err=>{
      console.log("ERROR", err);
      throw err
  });

答案 1 :(得分:0)

您可以像这样使用async / await:

const checkUser = async () => {        
    await user.exists();
    await user.verifyPassword();
    await user.isApproved();
    console.log("Login successful");        
}