通过Play Controller-Action中的#flatMap()链接Promise

时间:2014-08-28 17:29:03

标签: java playframework playframework-2.0 promise nonblocking

我想询问我所做的事情是否合适,或者是否有更好/更有效/更简单的方式。

情境:

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

    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的使用,我是正确使用它还是&#34;过度使用&#34;它?

1 个答案:

答案 0 :(得分:2)

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

另一方面,您向userPromise.flatMap提供的函数将返回Promise,因此它必须是flatMap,否则它将返回Promise<Promise<Result>>,您无法从控制器返回动作。