[Play 2.4 Java] Promise chaining structure

112 views
Skip to first unread message

Patrick Li

unread,
Feb 4, 2017, 7:04:31 PM2/4/17
to Play Framework
Hi,

If I want to chain two async processes together, i.e. two promises, one after another (not parallel), are there any differences between the two structures below, assuming both service1 and service2's doAsync() call all returns a promise.

Pseudo code below:

... ...
return service1.doAsync().flatmap(result1 -> {
   
return service2.doAsync(result1).map(result2 -> {
       
return result2;
   
});
});
... ...

... ...
return service1.doAsync().map(result1 -> {
   
return result1;
}).map(result1 -> {
   
return service2.doAsync(result1);
});
... ...

Thanks

Greg Methvin

unread,
Feb 4, 2017, 7:43:08 PM2/4/17
to play-framework
Your first example is the same as

return service1.doAsync().flatMap(result1 -> service2.doAsync(result1));

and the second is equivalent to

return service1.doAsync().map(result1 -> service2.doAsync(result1));

The difference is that by using flatMap you'll get a Promise<R2> (where R2 is the type of result2), and using map you'll get Promise<Promise<R2>>. Generally you want to use flatMap since the user of your method/API doesn't usually care whether an error happened at a particular step of the computation, and working with nested promises can be unwieldy.

Greg

--
You received this message because you are subscribed to the Google Groups "Play Framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framework+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/eb9a9b09-be69-49bc-908c-0bd3a8f80721%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Greg Methvin
Tech Lead - Play Framework

Patrick Li

unread,
Feb 4, 2017, 10:04:01 PM2/4/17
to Play Framework
So, if I change my 2nd code snippet to use flatmap like below, there would essentially be no difference, other than the 1st example has a nested structure and 2nd one does not?

... ...
return service1.doAsync().flatmap(result1 -> {

   
return result1;
}).map(result1 -> {
   
return service2.doAsync(result1);
});
... ...
To unsubscribe from this group and stop receiving emails from it, send an email to play-framewor...@googlegroups.com.

Greg Methvin

unread,
Feb 4, 2017, 10:57:10 PM2/4/17
to play-framework
You're mapping using the identity function (result1 -> result1) so initially that map call does nothing, since the value is returned unchanged. That's why I simplified the code in my reply. flatMap probably wouldn't work there since the function given to flatMap needs to return a Promise (unless service1.doAsync is returning a Promise<Promise<Foo>> which seems weird).

If you change the second map call to flatMap(result1 -> service2.doAsync(result1)), then it would be functionally equivalent to the first example. Basically, you should use flatMap when you want to do some other async operation and flatten the nested promises.

To unsubscribe from this group and stop receiving emails from it, send an email to play-framework+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/ca491dfb-02a5-4a3c-a057-9f0d576833c9%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Patrick Li

unread,
Feb 5, 2017, 12:56:19 PM2/5/17
to Play Framework
Thanks for the response Greg.

Would there be any cases to use the nested structure over the flattened one?
Reply all
Reply to author
Forward
0 new messages