如何使用promises构建复杂的if / then链?

时间:2015-02-13 14:42:40

标签: coffeescript promise bluebird

具体而言,bluebird兼容承诺

伪代码如下所示

if authentication
  db.findUser(authentication.userId).then (dbUser) ->
    sessionLogin dbUser
    # Done!
else
  if isSession req.user
    db.findUser(req.user.id).then (dbUser) ->
      db.addUserAuth(req.user.id, authentication).then (dbAuth) ->
        return
  else
    db.createUser(userDetails).then (dbUser) ->
      db.addUserAuth(dbUser.id, authentication).then (dbAuth) ->
        return

# Once all of that is done, do the following

if cookieSet
  db.findInvite(cookie.invitation).then (dbInvitation) ->
    if dbInvitation.Team
      db.createTeamMember(dbInvitation.Team, dbUser.id).then ->
        db.updateInvitation(marked: true).then ->
          done
    else
      done
else
  done

我不一定要找到确切的代码,伪代码或想法会做得很好。顺便说一下,这是用CoffeeScript编写的,尽管这并不重要。

2 个答案:

答案 0 :(得分:3)

嗯,承诺链但他们没有神奇地抽象分支逻辑,如if / else - 你仍然会使用条件。你的代码非常回调 - 你可以利用promises是值的代理并大大简化它:

if authentication
  user = db.findUser(authentication.userId)
  user_login = user.then (dbUser) -> sessionLogin dbUser 
  auth_user = user.return(user_login).return(user) # wait but keep value
else
  user = db.findUser(req.user.id) if isSession req.user else db.createUser(userDetails)
  auth_user = user.then(user->db.addUserAuth(req.user.id, authentication)).return(user)

auth_user.then (user) -> 
  if cookieSet
    db.findInvite(cookie.invitation)
.then (invite) ->
    if invite and invite.Team
      db.createTeamMember(dbInvitation.Team, dbUser.id)
.then val ->
   db.updateInvitation(marked: true) if val

答案 1 :(得分:1)

实际上看起来并没有什么不同,只是把承诺放在一起:

(if authentication
  db.findUser(authentication.userId).then (dbUser) ->
    sessionLogin dbUser
    .return dbUser
else
  (if isSession req.user
    db.findUser(req.user.id)
  else
    db.createUser(userDetails)
  ).then (dbUser) ->
    db.addUserAuth(dbUser.id, authentication)
    .return dbUser
).then (dbUser) ->
  if cookieSet
    db.findInvite(cookie.invitation).then (dbInvitation) ->
      if dbInvitation.Team
        db.createTeamMember(dbInvitation.Team, dbUser.id).then ->
          db.updateInvitation(marked: true)
.then ->
  done