【问题标题】:Chaining of Promises via #flatMap() in Play Controller-Action在 Play Controller-Action 中通过 #flatMap() 链接 Promise
【发布时间】:2014-08-28 17:29:02
【问题描述】:

我想问一下我做的是否合适,或者有没有更好/更高效/更简单的方法。

场景:

  1. 用户使用电子邮件地址和密码登录,被路由到 login()-action
  2. 如果用户已经在数据库中并且密码经过哈希处理,则向数据库用户进行身份验证并返回结果承诺
  3. 如果用户不在数据库中或没有密码哈希,请使用登录数据执行 Web 服务请求并从响应中解析状态 -> 返回 Status-instance
  4. 检查用户的状态并返回一个结果承诺

代码:

public Promise<Result> login() {
    Promise<User> userPromise = Promise.promise(() -> User.findByName(login.emailAddress));
    return userPromise.flatMap(user -> {
        if (user != null && user.hasPassword()) {
            if (user.authenticate(login.password)) {
                return Promise.pure(ok("login successful")));
            }
            // password did not match
            return Promise.pure(unauthorized());
        }

        // user has no password-hash stored, so do a webservice-request instead
        final WSRequestHolder holderWithParams =
                getWSRequestHolderForUserStatus(login.emailAddress, login.password);

        final Promise<Status> statusPromise =
                holderWithParams.get().flatMap(this::parseStatusFromResponse);

        return statusPromise.flatMap(status -> {
            if (status != null) {
                if (status.isValid()) {
                    return Promise.pure(ok("login successful")));
                }
                // not a valid status, return unauthorized
                return Promise.pure(unauthorized());
            }
            return Promise.pure(badRequest("response parsing error");
        });
    });
}

我的问题:

  1. 我是否做错了什么或不必要的事情,如果是:什么是正确、更简单或更有效的方法?
  2. 我是否了解 Promise 和 flatMaps 的使用,我是在正确使用它还是“过度使用”它?

【问题讨论】:

    标签: java playframework playframework-2.0 promise nonblocking


    【解决方案1】:

    .flatMap 用于当您提供给它的函数的某些返回值返回 Promise 本身时。如果您所做的只是返回非期货,那么您可以只使用.map,所以最后一个.flatMap 似乎不需要是.flatMap,因为您只需将所有结果值包装在Promise.pure 中,使用@ 987654327@ 您可以直接返回这些值,而无需进一步将它们装箱到 Promise 中。

    另一方面,您提供给 userPromise.flatMap 的函数将返回 Promise,因此它必须是一个 flatMap,否则它又会返回您无法从控制器操作返回的 Promise&lt;Promise&lt;Result&gt;&gt;

    【讨论】:

    • 基本上你看到的一切都是我给userPromise.flatMap的函数的一部分,所以我担心最后一个.flatMap不能是地图,否则返回类型不匹配。但是:我的holderWithParams.get() 上的flatMap 是使用Status 所必需的,还是只是map?那是我不太确定的部分,我认为它必须是一个 flatMap 因为 Status 的单个 Promise 扁平化。
    • 为了简化我的问题:返回类型(Promise&lt;A&gt;A)是flatMapmap 之间的唯一区别吗?如果是这样,我确实可以节省最后一个flatMaps,我认为如果我想重新使用返回的对象,因为“扁平化”(无论这究竟意味着什么),这是必要的。
    • 好的,感谢您的澄清,我接受了这个答案,因为如果我只有单个对象作为类型(没有集合),我不确定 flatMap 是否还有其他含义。
    猜你喜欢
    • 2017-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-03
    • 2016-12-22
    • 2018-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多