GWT_TOOLS=path/to/gwt-tools.
void makeServerRequest(MethodCallback<Void> callback);
Future<Void> makeServerRequest();
public interface Future<T> { public void onComplete(Consumer<Try<T>> consumer); public void handle(Consumer<Throwable> errorHandler, Consumer<T> successHandler); public void forEach(Consumer<T> consumer); public <R> Future<R> map(Function<T, R> function); public <R> Future<R> flatMap(Function<T, Future<R>> function); public T get(); }
public class FutureImpl<T> implements Future<T> { private List<Consumer<Try<T>>> completeFunctions = new ArrayList<>(); private Option<Try<T>> result = Option.getEmpty(); public FutureImpl() { } @Override public void onComplete(Consumer<Try<T>> consumer) { result.forEach(consumer::accept); completeFunctions.add(consumer); } @Override public void handle(Consumer<Throwable> errorHandler, Consumer<T> successHandler) { onComplete((result) -> { if (result.isSuccess()) successHandler.accept(result.get()); else errorHandler.accept(result.getCause()); }); } public void completeWithResult(Try<T> result) { this.result = Option.create(result); for (Consumer<Try<T>> completeFunction : completeFunctions) { completeFunction.accept(result); } } public void completeWithSuccess(T result) { completeWithResult(new Success<T>(result)); } public void completeWithFailure(Throwable ex) { completeWithResult(new Failure<T>(ex)); } @Override public void forEach(Consumer<T> consumer) { onComplete((result) -> { if (result.isSuccess()) { consumer.accept(result.get()); } }); } @Override public <R> Future<R> map(Function<T, R> function) { FutureImpl<R> future = new FutureImpl<R>(); onComplete((result) -> { if (result.isSuccess()) { future.completeWithSuccess(function.apply(result.get())); } }); return future; } @Override public <R> FutureImpl<R> flatMap(Function<T, Future<R>> function) { FutureImpl<R> mapped = new FutureImpl<R>(); onComplete((result) -> { if (result.isSuccess()) { Future<R> f = function.apply(result.get()); f.onComplete(mapped::completeWithResult); } }); return mapped; } @Override public T get() { return result.get().get(); } }
@Path("../service") @Consumes(MediaType.APPLICATION_JSON) public interface CallbackCountryService extends RestService { @GET @Path("/countires/") public void getCountries(MethodCallback<List<Country>> callback); @GET @Path("/regions/{countryId}/") public void getRegions(@PathParam("countryId") Integer countryId, MethodCallback<List<Region>> callback); }
countryService.getCountries(new MethodCallback<List<Country>>() { @Override public void onFailure(Method method, Throwable exception) { } @Override public void onSuccess(Method method, List<Country> response) { view.displayCountries(response); } });
countryService.getCountries().forEach(view::displayCountries);
countryService.getCountries(new MethodCallback<List<Country>>() { @Override public void onFailure(Method method, Throwable exception) { view.displayError(exception.getMessage()); } @Override public void onSuccess(Method method, List<Country> response) { view.displayCountries(response); } });
countryService.getCountries().handle(t -> view.displayError(t.getMessage()), view::displayCountries);
Future.handle
method. One is responsible for handling the error, the second is responsible for handling successful execution with the result.
countryService.getCountries(new MethodCallback<List<Country>>() { @Override public void onFailure(Method method, Throwable exception) { view.displayError(exception.getMessage()); } @Override public void onSuccess(Method method, List<Country> response) { countryService.getRegions(response.get(0).getId(), new MethodCallback<List<Region>>() { @Override public void onFailure(Method method, Throwable exception) { view.displayError(exception.getMessage()); } @Override public void onSuccess(Method method, List<Region> response) { view.displayRegions(response); } }); } });
countryService.getCountries() .map(countries -> countries.get(0).getId()) .flatMap(countryService::getRegions) .handle(err -> view.displayError(err.getMessage()), view::displayRegions);
Future<List> Future, countryId . Future . , , .
.
Future . .
:
Future<List> Future, countryId . Future . , , .
.
Future . .
:
Future<List<Future<List<Region>>>> regionFutures = countryService.getCountries() .map( countries -> countries.map(country -> countryService.getRegions(country.getId())) );
List<Future> Future<List>. Future , Future .
Future<Future<List<List<Region>>>> regions = regionFutures.map(FutureUtils::toFutureOfList);
Future<Future> Future, :
FutureUtils .flatten(regions) .map(ListUtils::flatten) .handle(err -> view.displayError(err.getMessage()), view::displayRegions());
Source: https://habr.com/ru/post/218731/