本文介绍了在Play Controller-Action中通过#flatMap()链接承诺的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想问我正在做的事情是否合适,或者是否有更好/更有效/更简单的方法.

I'd like to ask if what I'm doing is suitable or if there is a better/more efficient/simpler way.

场景:

  1. 用户使用电子邮件地址和密码登录,并被路由到login()-动作
  2. 如果用户已经在数据库中并且密码被散列,请与数据库用户进行身份验证并返回结果承诺
  3. 如果用户不在数据库中或没有密码哈希,请使用登录数据进行Web服务请求,并从响应中解析状态->返回Status -instance
  4. 检查用户状态并返回结果承诺
  1. User logs in with e-mail-address and password, gets routed to the login()-action
  2. If the user is already in the DB and has a password hashed, authenticate with the DB-user and return result-promise
  3. If user is not in the DB or has no password-hash, do a web-service request with the login-data and parse the status from the response -> return a Status-instance
  4. Check the status of the user and return a result-promise

代码:

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. 我了解Promises和flatMaps的使用吗,我是在正确使用它还是在过度使用"它?

推荐答案

.flatMap适用于您赋予函数的某些返回值本身返回Promise的情况.如果您所做的只是返回非期货,则可以使用.map,因此最后一个.flatMap似乎不需要是.flatMap,因为您只需将所有结果值包装在Promise.pure中,并用.map您可以直接返回这些值,而无需在Promise中将它们进一步装箱.

.flatMap is for when some return value of the function you give to it returns a Promise itself. If all you do is return non-futures, then you can just use .map, so the last .flatMap does not seem to need be a .flatMap since you just wrap all the results values in Promise.pure, with .map you can just return those values without further boxing them in a Promise.

您赋予userPromise.flatMap的函数将返回Promise,因此它必须是flatMap,否则它将返回Promise<Promise<Result>>,您无法从控制器操作中返回.

The function you give to userPromise.flatMap on the other hand will return a Promise so it must be a flatMap or else it in turn will return Promise<Promise<Result>> which you cannot return from your controller action.

这篇关于在Play Controller-Action中通过#flatMap()链接承诺的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-01 19:28