1Promises::Cookbook::ScaUlsaeFrutCuornetsrCiobPmurptoaemrdiissPeoesnr:(l:3C)Dooockubmoeonkt:a:tSicoanlaFuturesComparison(3)
2
3
4

NAME

6       Promises::Cookbook::ScalaFuturesComparison - A comparison of Scala
7       Futures with Promises
8

VERSION

10       version 1.04
11

DESCRIPTION

13       Here is the example Scala code, it assumes a function called "fetch"
14       which when given a URL will return a Future.
15
16           def getThumbnail(url: String): Future[Webpage] = {
17               val promise = new Promise[Webpage]
18               fetch(url) onSuccess { page =>
19                   fetch(page.imageLinks(0)) onSuccess { p =>
20                       promise.setValue(p)
21                   } onFailure { exc =>
22                       promise.setException(exc)
23                   }
24               } onFailure { exc =>
25                   promise.setException(exc)
26               }
27               promise
28           }
29
30       If we take this and translate this into Perl code using the
31       Mojo::UserAgent library, the "fetch" function would look like this:
32
33           sub fetch {
34               state $ua = Mojo::UserAgent->new;
35               my $url   = shift;
36               my $d     = deferred;
37               $ua->get($url => sub {
38                   my ($ua, $tx) = @_;
39                   $d->resolve( $tx );
40               });
41               $d->promise;
42           }
43
44       And if we were to take the "get_thumbnail" function and translate it
45       exactly, we would end up with this:
46
47           sub get_thumbnail {
48               my $url = shift;
49               my $d   = deferred;
50               fetch( $url )->then(
51                   sub {
52                       my $tx = shift;
53                       fetch( $tx->res->dom->find('img')->[0]->{'src'} )->then(
54                           sub { $d->resolve( $_[0] ) },
55                           sub { $d->reject( $_[0] ) },
56                       )
57                   },
58                   sub { $d->reject( $_[0] ) }
59               );
60               $d->promise;
61           }
62
63       Scala Futures have a method called "flatMap", which takes a function
64       that given value will return another Future. Here is an example of how
65       the "getThumbnail" method can be simplified by using it.
66
67           def getThumbnail(url: String): Future[Webpage] =
68               fetch(url) flatMap { page =>
69                    fetch(page.imageLinks(0))
70               }
71
72       But since our "then" method actually creates a new promise and wraps
73       the callbacks to chain to that promise, we don't need this "flatMap"
74       combinator and so this, Just Works.
75
76           sub get_thumbnail {
77               my $url = shift;
78               fetch( $url )->then(
79                   sub {
80                       my $tx = shift;
81                       fetch( $tx->res->dom->find('img')->[0]->{'src'} );
82                   }
83               );
84           }
85
86       Scala Futures also have a "rescue" method which can serve as a kind of
87       catch block that potentially will return another Future.
88
89           val f = fetch(url) rescue {
90               case ConnectionFailed =>
91                 fetch(url)
92           }
93
94       Just as with "flatMap", since our callbacks are wrapped and chained
95       with a new Promise, we can do a rescue just by using the error callback
96       The Promise returned by "fetch" will get chained and so this will
97       depend on it.
98
99           sub get_thumbnail {
100               my $url = shift;
101               fetch( $url )->then(
102                   sub {
103                       my $page = shift;
104                       fetch( $page->image_links->[0] );
105                   },
106                   sub {
107                       given ( $_[0] ) {
108                           when ('connection_failed') {
109                               return fetch( $url );
110                           }
111                           default {
112                               return "failed";
113                           }
114                       }
115                   }
116               );
117           }
118
119       TODO ... figure out how retry can be generic ...
120

SEE ALSO

122       Systems Programming at Twitter -
123       <http://monkey.org/~marius/talks/twittersystems/>
124

AUTHOR

126       Stevan Little <stevan.little@iinteractive.com>
127
129       This software is copyright (c) 2020, 2019, 2017, 2014, 2012 by Infinity
130       Interactive, Inc.
131
132       This is free software; you can redistribute it and/or modify it under
133       the same terms as the Perl 5 programming language system itself.
134
135
136
137perl v5.32.0                     P2r0o2m0i-s0e7s-:2:8Cookbook::ScalaFuturesComparison(3)
Impressum