Scala 异步/回调代码重写

2024-01-26

简单的代码应该通过检查用户,用户是否处于活动状态,然后更新上次登录日期时间。

  def authenticate() = Action.async { implicit request => 
    loginForm.bindFromRequest.fold(
        errors => Future.successful(BadRequest(views.html.logon(errors))),
        usersData =>{
           val cursor =  this.collection.find(BSONDocument("name" -> usersData._1)).one[Account].map(_.filter(p=>p.password == hashedPass(usersData._2, usersData._1)))
           cursor.flatMap(p => p match {
               case None => Future.successful(BadRequest(views.html.logon(loginForm.withGlobalError("user/pass incorect!!!"))))
               case Some(user) => {
                 if(!user.active) 
                   Future.successful(BadRequest(views.html.logon(loginForm.withGlobalError("inactive!!!"))))
                 else collection.update(BSONDocument("_id" -> user.id), 
                          BSONDocument("$set" -> 
                          BSONDocument("lastLogin" -> BSONDateTime(new org.joda.time.DateTime().getMillis()))))
                          .flatMap(x => gotoLoginSucceeded(user.id.stringify))

               }
               })
            })
  }  

如何将其重写为更少的 flatMap/map 意大利面?

另一种解决方案

def authenticate() = AsyncStack { implicit request => 
loginForm.bindFromRequest.fold(
    errors => Future.successful(BadRequest(views.html.logon(errors))),
    usersData =>{
      for{
        user <- this.collection.find(BSONDocument("name" -> usersData._1)).one[Account].map(_.filter(p=>p.password == hashedPass(usersData._2, usersData._1)))
        update <- {
         lazy val update = collection.update(BSONDocument("_id" -> user.get.id), 
         BSONDocument("$set" -> 
         BSONDocument("lastLogin" -> BSONDateTime(new org.joda.time.DateTime().getMillis()))))
         update
        }
        result <- {
         lazy val result = gotoLoginSucceeded(user.get.id.stringify)
         result
        } 
      } yield
        if(user.isEmpty) BadRequest(views.html.logon(loginForm.withGlobalError("login\pass mismatch")))
        else if(!user.get.active) BadRequest(views.html.logon(loginForm.withGlobalError("inactive")))
        else if(update.err.isEmpty) result
        else  InternalServerError(views.html.logon(loginForm.withGlobalError("server error")))
        })

}


我可能会将代码重构为如下所示:

def authenticate() = Action.async { implicit request => 
  loginForm.bindFromRequest.fold(
     hasErrors = displayFormWithErrors,
     success = loginUser)
}  

private def displayFormWithErrors[T](errors:Form[T]) = 
  Future.successful(BadRequest(views.html.logon(errors)))

private def loginUser(userData:(String, String)) = {
  val (username, password) = userData

  findUser(username, password)
    .flatMap {
      case None => 
        showLoginFormWithError("user/pass incorect!!!")
      case Some(user) if (!user.active) =>
        showLoginFormWithError("inactive!!!")
      case Some(user) =>
        updateUserAndRedirect(user)
  }
}

private def findUser(username:String, password:String) =
  this.collection
    .find(BSONDocument("name" -> username))
    .one[Account]
    .map(_.filter(_.password == hashedPass(password, username)))

private def showLoginFormWithError(error:String) = 
  Future.successful(BadRequest(
    views.html.logon(loginForm.withGlobalError(error))))

private def updateUserAndRedirect(user:Account) = 
  updateLastLogin(user)
    .flatMap(_ => gotoLoginSucceeded(user.id.stringify))

private def updateLastLogin(user:Account) = 
  collection
    .update(BSONDocument("_id" -> user.id), 
              BSONDocument("$set" -> 
              BSONDocument("lastLogin" -> 
              BSONDateTime(new JodaDateTime().getMillis()))))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Scala 异步/回调代码重写 的相关文章

随机推荐

  • 如何使用 jQuery UI 的 droppable 排序和创建多个文本字段?

    设想 我希望我的用户能够通过将产品拖到可放置和可排序的列表中来创建购物清单 根据产品在列表中的位置以及产品的价值 必须填充此表单的文本字段 jsFiddle http jsfiddle net imjp 5NWAQ 1 http jsfid
  • 如何为使用 AJAX 获取的页面或内容添加“书签”?

    如何为使用 AJAX 获取的页面或内容添加 书签 看起来 如果我们只是将详细信息添加到 锚点 然后使用路由 甚至在 PHP 代码或 Ruby on Rails 的 Route rb 中 捕获该部分 然后显示内容或页面 这似乎很容易因此 显示
  • 从 PHP CLI 脚本运行命令之前导出 shell 环境变量

    我有一个使用的脚本通路 http www php net manual en function passthru php运行命令 在运行此命令之前我需要设置一些 shell 环境变量 否则它将无法找到它的库 我尝试过以下方法 putenv
  • 如何在 Laravel 5 请求类中验证 Money

    我的验证类看起来像这样
  • DOM 到 XML 转换器逻辑

    有人可以向我解释一下为什么吗DOM to XML变压器将输出转换为Web Service Consumer到 XML 字符串表示形式 Web 服务使用者的输出是org mule module ws consumer NamespaceRes
  • 带有注释和缓存的 Spring Batch

    有谁有Spring Batch 使用注释 的好例子来缓存处理器可以访问的引用表 我只需要一个简单的缓存 运行一个返回一些 byte 的查询并将其保留在内存中直到作业执行 感谢有关此主题的任何帮助 Thanks A JobExecutionL
  • LINQ to XML 在标记之间生成 \r\n?

    我正在生成具有以下结构的 XElement
  • g++ (mingw) 表示,to_string 不是 std 的成员

    我正在制作一个小型词汇记忆程序 其中单词会随机闪现给我以了解含义 正如 Bjarne Stroustroup 告诉我们的那样 我想使用标准 C 库 但我一开始就遇到了一个看似奇怪的问题 我想改变一个long整数到std string以便能够
  • iOS5 ARC 从后台选择器调度 NSTimers 安全吗?

    我正在尝试调试我的应用程序 我一直在我的非弧代码中使用一些 NSTimer 实例 如下所示 来自主线程 NSTimer scheduledTimerWithTimeInterval 5 target musicPlayer selector
  • ResXFileCodeGenerator - 覆盖输出(想要使用自定义资源管理器)

    我创建了一个继承自 ResourceManager 的类 我的问题是 如果我更改 Resources Designer cs 来使用它 e g private static global System Resources ResourceM
  • 检索最后(最新)不同的最高值

    我想检索最新的requestid来自表 tbl 的报价提案 此处为特定客户 ID 3 在此示例中为 ID 2 和 ID 4 表 tbl 请求 请求 ID 客户 ID 6 2 7 4 8 3 9 3 Table tblquoteproposa
  • 读取整个文件并在lua中打印

    我是 Lua 的初学者 只有一点 C 经验 目前我正在使用 ZeroBrane Studio 作为 IDE 我正在尝试读取一个文件并将整个文件打印到控制台 如下所示 function readAll file local f io open
  • 在Spring Boot 2中,是否可以自动生成具有唯一约束的JoinTable?

    我正在使用 Spring Boot 2 和 PostGres 10 我创建了以下实体 角色和权限 Data Entity Table name Roles public class Role public enum Name USER AD
  • __NSArrayM insertObject:atIndex:];对象不能为零

    我是一个iOS开发新手 我想做加密和解密 我的问题如下 当我运行代码时 解密在模拟器中工作正常 但它无法在 iPhone 设备上运行 我收到如下错误消息 NSArrayM insertObject atIndex object cannot
  • 根据其他值添加列

    我有一个数据框 其中有数百万行和三列 标记为 关键字 展示次数 点击次数 我想添加一列 其中的值取决于此函数的评估 isType lt function Impressions Clicks if Impressions gt 1 Clic
  • 强制 Psych 将 YAML 映射读取为给定类的对象

    我有课Foo应该以最人性化的方式序列化为文本文件 我使用 Ruby 的默认 YAML Psych 和自定义encode with 我的问题是 如果我删除 ruby object Foo像这样 def encode with coder co
  • Azure Verizon CDN - 100% 缓存 CONFIG_NOCACHE

    几天前 我设置了 Azure Verizon Premium CDN 如下所示 Origin Azure Web 应用程序 NET MVC 5 网站 Settings 自定义域 无地理过滤 缓存规则 标准缓存 不关心参数 压缩 启用 优化用
  • 动态赋值给宏函数.pch文件和检查条件.pch文件

    pch 正如其名称所示 显示了预编译器标头 我在文件中定义了一个宏 以便应用程序可以在应用程序编译的一开始就决定 我需要的是 可以通过动态分配值来加载任何宏 例如NSUserDefaults并检查条件 pch文件本身 如果用户从屏幕 开关
  • Spring在运行时动态声明bean

    我想知道以下是否可能 出于测试目的 我希望在应用程序上下文中为不同的测试声明不同的模拟类 这些是使用 Jersey REST 客户端的验收测试 有没有办法在运行时动态声明bean Spring 是否有 API 允许在加载上下文后更改应用程序
  • Scala 异步/回调代码重写

    简单的代码应该通过检查用户 用户是否处于活动状态 然后更新上次登录日期时间 def authenticate Action async implicit request gt loginForm bindFromRequest fold e