Chaining of Promises via #flatMap() in Play Controller-Action

房东的猫 提交于 2019-12-08 04:00:36

问题


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

Scenario:

  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

Code:

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");
        });
    });
}

My questions:

  1. Am I doing anything wrong or unnecessary, and if yes: what is the correct, easier or more efficient way?
  2. Did I understand the use of Promises and flatMaps, am I using it correctly or "over-using" it?

回答1:


.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.

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.



来源:https://stackoverflow.com/questions/25554687/chaining-of-promises-via-flatmap-in-play-controller-action

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!