|
NAMEPromises::Cookbook::ScalaFuturesComparison - A comparison of Scala Futures with PromisesVERSIONversion 0.94DESCRIPTIONHere is the example Scala code, it assumes a function called "fetch" which when given a URL will return a Future.def getThumbnail(url: String): Future[Webpage] = { val promise = new Promise[Webpage] fetch(url) onSuccess { page => fetch(page.imageLinks(0)) onSuccess { p => promise.setValue(p) } onFailure { exc => promise.setException(exc) } } onFailure { exc => promise.setException(exc) } promise } If we take this and translate this into Perl code using the Mojo::UserAgent library, the "fetch" function would look like this: sub fetch { state $ua = Mojo::UserAgent->new; my $url = shift; my $d = deferred; $ua->get($url => sub { my ($ua, $tx) = @_; $d->resolve( $tx ); }); $d->promise; } And if we were to take the "get_thumbnail" function and translate it exactly, we would end up with this: sub get_thumbnail { my $url = shift; my $d = deferred; fetch( $url )->then( sub { my $tx = shift; fetch( $tx->res->dom->find('img')->[0]->{'src'} )->then( sub { $d->resolve( $_[0] ) }, sub { $d->reject( $_[0] ) }, ) }, sub { $d->reject( $_[0] ) } ); $d->promise; } Scala Futures have a method called "flatMap", which takes a function that given value will return another Future. Here is an example of how the "getThumbnail" method can be simplified by using it. def getThumbnail(url: String): Future[Webpage] = fetch(url) flatMap { page => fetch(page.imageLinks(0)) } But since our "then" method actually creates a new promise and wraps the callbacks to chain to that promise, we don't need this "flatMap" combinator and so this, Just Works. sub get_thumbnail { my $url = shift; fetch( $url )->then( sub { my $tx = shift; fetch( $tx->res->dom->find('img')->[0]->{'src'} ); } ); } Scala Futures also have a "rescue" method which can serve as a kind of catch block that potentially will return another Future. val f = fetch(url) rescue { case ConnectionFailed => fetch(url) } Just as with "flatMap", since our callbacks are wrapped and chained with a new Promise, we can do a rescue just by using the error callback The Promise returned by "fetch" will get chained and so this will depend on it. sub get_thumbnail { my $url = shift; fetch( $url )->then( sub { my $page = shift; fetch( $page->image_links->[0] ); }, sub { given ( $_[0] ) { when ('connection_failed') { return fetch( $url ); } default { return "failed"; } } } ); } TODO ... figure out how retry can be generic ... SEE ALSOSystems Programming at Twitter - <http://monkey.org/~marius/talks/twittersystems/>AUTHORStevan Little <stevan.little@iinteractive.com>COPYRIGHT AND LICENSEThis software is copyright (c) 2014 by Infinity Interactive, Inc..This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
Visit the GSP FreeBSD Man Page Interface. |