RxJava Fetching Observables In Parallel

前端 未结 2 1390
攒了一身酷
攒了一身酷 2020-11-30 18:13

I need some help in implementing parallel asynchronous calls in RxJava. I have picked up a simple use case wherein the FIRST call fetches (rather searches) a list of product

2条回答
  •  没有蜡笔的小新
    2020-11-30 18:49

    People who are still @ JDK 7, whose IDE doesn't automatically detect JDK 8 source just yet and what to try out the above brilliant response (and explanation) by @benjchristensen can use this shamelessly refractored, JDK 7, code. Kudos to @benjchristensen for an amazing explanation and example !

    import java.util.List;
    
    import rx.Observable;
    import rx.Subscriber;
    import rx.functions.Action0;
    import rx.functions.Func1;
    import rx.functions.Func2;
    import rx.schedulers.Schedulers;
    
    public class ParallelExecutionExample
    {
    
        public static void main(String[] args)
        {
            final long startTime = System.currentTimeMillis();
    
            Observable searchTile = getSearchResults("search term")
                    .doOnSubscribe(new Action0()
                            {
    
                                @Override
                                public void call()
                                {
                                    logTime("Search started ", startTime);
                                }
                    })
                    .doOnCompleted(new Action0()
                            {
    
                                @Override
                                public void call()
                                {
                                    logTime("Search completed ", startTime);
                                }
                    });
            Observable populatedTiles = searchTile.flatMap(new Func1>()
            {
    
                @Override
                public Observable call(final Tile t)
                {
                    Observable reviews = getSellerReviews(t.getSellerId())
                            .doOnCompleted(new Action0()
                                    {
    
                                        @Override
                                        public void call()
                                        {
                                            logTime("getSellerReviews[" + t.id + "] completed ", startTime);
                                        }
                            });
                    Observable imageUrl = getProductImage(t.getProductId())
                            .doOnCompleted(new Action0()
                                    {
    
                                        @Override
                                        public void call()
                                        {
                                            logTime("getProductImage[" + t.id + "] completed ", startTime);
                                        }
                            });
                    return Observable.zip(reviews, imageUrl, new Func2()
                    {
    
                        @Override
                        public TileResponse call(Reviews r, String u)
                        {
                            return new TileResponse(t, r, u);
                        }
                    })
                            .doOnCompleted(new Action0()
                                    {
    
                                        @Override
                                        public void call()
                                        {
                                            logTime("zip[" + t.id + "] completed ", startTime);
                                        }
                            });
                }
            });
    
            List allTiles = populatedTiles
                    .toList()
                    .doOnCompleted(new Action0()
                            {
    
                                @Override
                                public void call()
                                {
                                    logTime("All Tiles Completed ", startTime);
                                }
                    })
                    .toBlocking()
                    .single();
        }
    
        private static Observable getSearchResults(String string)
        {
            return mockClient(new Tile(1), new Tile(2), new Tile(3));
        }
    
        private static Observable getSellerReviews(int id)
        {
            return mockClient(new Reviews());
        }
    
        private static Observable getProductImage(int id)
        {
            return mockClient("image_" + id);
        }
    
        private static void logTime(String message, long startTime)
        {
            System.out.println(message + " => " + (System.currentTimeMillis() - startTime) + "ms");
        }
    
        private static  Observable mockClient(final T... ts)
        {
            return Observable.create(new Observable.OnSubscribe()
            {
    
                @Override
                public void call(Subscriber s)
                {
                    try
                    {
                        Thread.sleep(1000);
                    }
                    catch (Exception e)
                    {
                    }
                    for (T t : ts)
                    {
                        s.onNext(t);
                    }
                    s.onCompleted();
                }
            })
                    .subscribeOn(Schedulers.io());
            // note the use of subscribeOn to make an otherwise synchronous Observable async
        }
    
        public static class TileResponse
        {
    
            public TileResponse(Tile t, Reviews r, String u)
            {
                // store the values
            }
    
        }
    
        public static class Tile
        {
    
            private final int id;
    
            public Tile(int i)
            {
                this.id = i;
            }
    
            public int getSellerId()
            {
                return id;
            }
    
            public int getProductId()
            {
                return id;
            }
    
        }
    
        public static class Reviews
        {
    
        }
    } 
    

提交回复
热议问题