RX之异步操作(start、toAsync、startFuture、deferFuture、fromAction、fromRunnable、forEachFuture、runAsync)

需要在buld.gradle中加入compile 'io.reactivex:rxjava-async-util:0.21.0'

一、start

返回一个Observable,它发射一个类似于函数声明的值。编程语言有很多种方法可以从运算结果中获取值,它们的名字一般叫functions, futures, actions, callables, runnables等等。在Start目录下的这组操作符可以让它们表现得像Observable,因此它们可以在Observables调用链中与其它Observable搭配使用。Start操作符的多种RxJava实现都属于可选的rxjava-async模块。

rxjava-async模块包含start操作符,它接受一个函数作为参数,调用这个函数获取一个值,然后返回一个会发射这个值给后续观察者的Observable。

注意:这个函数只会被执行一次,即使多个观察者订阅这个返回的Observable。

 Observable<Integer> observable = Async.start(new Func0<Integer>() {
            @Override
            public Integer call() {
                //函数内为异步操作
                try {
                    Thread.sleep(5 * 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return 20;
            }
        });

        Subscriber<Integer> subscriber = new Subscriber<Integer>() {
            @Override
            public void onNext(Integer v) {
                Log.e(TAG, "onNext................." + v);

            }

            @Override
            public void onCompleted() {
                Log.e(TAG, "onCompleted.................");
            }

            @Override
            public void onError(Throwable e) {
                Log.e(TAG, "onError.....................");
            }
        };

        observable.subscribe(subscriber);
5s后才输出打印结果
运行结果:


二、toAsync

rxjava-async模块还包含这几个操作符:toAsyncasyncAction, 和asyncFunc。它们接受一个函数或一个Action作为参数。对于函数(functions),这个操作符调用这个函数获取一个值,然后返回一个会发射这个值给后续观察者的Observable(和start一样)。对于动作(Action),过程类似,但是没有返回值,在这种情况下,这个操作符在终止前会发射一个null值。

注:这个函数或动作只会被执行一次,即使多个观察者订阅这个返回的Observable。

 Func0<Observable<Integer>> func0 = Async.toAsync(new Func0<Integer>() {
            @Override
            public Integer call() {
                //函数内为异步操作
                try {
                    Thread.sleep(5 * 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return 20;
            }
        });
        Observable<Integer> observable = func0.call();

        Subscriber<Integer> subscriber = new Subscriber<Integer>() {
            @Override
            public void onNext(Integer v) {
                Log.e(TAG, "onNext................." + v);

            }

            @Override
            public void onCompleted() {
                Log.e(TAG, "onCompleted.................");
            }

            @Override
            public void onError(Throwable e) {
                Log.e(TAG, "onError.....................");
            }
        };
        observable.subscribe(subscriber);

运行结果:


三、startFuture

xjava-async模块还包含一个startFuture操作符,传递给它一个返回Future的函数,startFuture会立即调用这个函数获取Future对象,然后调用Futureget()方法尝试获取它的值。它返回一个发射这个值给后续观察者的Observable。

final Future<Integer> future = Executors.newCachedThreadPool().submit(new Task());
        Observable<Integer> observable = Async.startFuture(new Func0<Future<Integer>>() {
            @Override
            public Future<Integer> call() {
                //函数内为异步操作
                return future;
            }
        });


        Subscriber<Integer> subscriber = new Subscriber<Integer>() {
            @Override
            public void onNext(Integer v) {
                Log.e(TAG, "onNext................." + v);

            }

            @Override
            public void onCompleted() {
                Log.e(TAG, "onCompleted.................");
            }

            @Override
            public void onError(Throwable e) {
                Log.e(TAG, "onError.....................");
            }
        };

        observable.subscribe(subscriber);

运行结果:

10s后才输出打印结果


四、deferFuture

deferFuture中的函数可以异步执行一些操作,当完成后返回一个Observable,但是这个Observable不会立刻发射数据,直到开始订阅时。 

rxjava-async模块还包含一个deferFuture操作符,传递给它一个返回Future的函数(这个Future返回一个Observable),deferFuture返回一个Observable,但是不会调用你提供的函数,知道有观察者订阅它返回的Observable。这时,它立即调用Futureget()方法,然后镜像发射get()方法返回的Observable发射的数据。

用这种方法,你可以在Observables调用链中包含一个返回Observable的Future对象。

 Observable<Long> observable = Observable.interval(1,TimeUnit.SECONDS).take(5);

        final Future<Observable<Integer>> future = Executors.newCachedThreadPool().submit(new ObservableTask());
        final Observable<Integer> observable1 = Async.deferFuture(new Func0<Future<Observable<Integer>>>() {
            @Override
            public Future<Observable<Integer>> call() {
                return future;
            }
        });

        final Subscriber<Integer> subscriber1 = new Subscriber<Integer>() {
            @Override
            public void onNext(Integer integer) {
                Log.e(TAG, "onNext1................." + integer);
            }

            @Override
            public void onCompleted() {
                Log.e(TAG, "onCompleted1.................");
            }

            @Override
            public void onError(Throwable e) {
                Log.e(TAG, "onError1.....................");
            }
        };

        Subscriber<Long> subscriber = new Subscriber<Long>() {
            @Override
            public void onNext(Long integer) {
                Log.e(TAG, "onNext................." + integer);
                if(integer == 4){
                    observable1.subscribe(subscriber1);
                }
            }

            @Override
            public void onCompleted() {
                Log.e(TAG, "onCompleted.................");
            }

            @Override
            public void onError(Throwable e) {
                Log.e(TAG, "onError.....................");
            }
        };


        observable.subscribe(subscriber);

运行结果:



五、fromAction

当fromAction()中的函数Action0执行完成后发射数据。Action无返回结果。rxjava-async模块还包含一个fromAction操作符,它接受一个Action作为参数,返回一个Observable,一旦Action终止,它发射这个你传递给fromAction的数据。

        final int result = 1;
        final Observable<Integer> observable = Async.fromAction(new Action0() {
            @Override
            public void call() {

                for(int i=1;i<10;i++){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

            }
        },result);

        final Subscriber<Integer> subscriber = new Subscriber<Integer>() {
            @Override
            public void onNext(Integer integer) {
                Log.e(TAG, "onNext1................." + integer);
            }

            @Override
            public void onCompleted() {
                Log.e(TAG, "onCompleted1.................");
            }

            @Override
            public void onError(Throwable e) {
                Log.e(TAG, "onError1.....................");
            }
        };

        observable.subscribe(subscriber);


运行结果:


六、fromCallable

当fromCallable中的函数运行完成后将其结果发射出去。rxjava-async模块还包含一个fromCallable操作符,它接受一个Callable作为参数,返回一个发射这个Callable的结果的Observable。

 final Observable<Integer> observable = Async.fromCallable(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                int result = 1;
                for(int i=1;i<10;i++){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    result *= i;
                }
                return result;
            }
        });

        final Subscriber<Integer> subscriber = new Subscriber<Integer>() {
            @Override
            public void onNext(Integer integer) {
                Log.e(TAG, "onNext1................." + integer);
            }

            @Override
            public void onCompleted() {
                Log.e(TAG, "onCompleted1.................");
            }

            @Override
            public void onError(Throwable e) {
                Log.e(TAG, "onError1.....................");
            }
        };

        observable.subscribe(subscriber);
运行结果:


七、fromRunnable

当run方法执行完成后发送传入的参数数据。rxjava-async模块还包含一个fromRunnable操作符,它接受一个Runnable作为参数,返回一个Observable,一旦Runnable终止,它发射这个你传递给fromRunnable的数据。

        //当runnable执行完成后所需发射的数据
        int result = 20;
         Observable<Integer> observable = Async.fromRunnable(new Runnable() {
             @Override
             public void run() {
                 for(int i=1;i<10;i++){
                     try {
                         Thread.sleep(1000);
                     } catch (InterruptedException e) {
                         e.printStackTrace();
                     }
                 }
             }
         },result);

         Subscriber<Integer> subscriber = new Subscriber<Integer>() {
            @Override
            public void onNext(Integer integer) {
                Log.e(TAG, "onNext1................." + integer);
            }

            @Override
            public void onCompleted() {
                Log.e(TAG, "onCompleted1.................");
            }

            @Override
            public void onError(Throwable e) {
                Log.e(TAG, "onError1.....................");
            }
        };

        observable.subscribe(subscriber);
运行结果:


八、forEachFuture

rxjava-async模块还包含一个forEachFuture操作符。它其实不算Start操作符的一个变体,而是有一些自己的特点。你传递一些典型的观察者方法(如onNext, onError和onCompleted)给它,Observable会以通常的方式调用它。但是forEachFuture自己返回一个Future并且在get()方法处阻塞,直到原始Observable执行完成,然后它返回,完成还是错误依赖于原始Observable是完成还是错误。

如果你想要一个函数阻塞直到Observable执行完成,可以使用这个操作符。


private void testForEachFuture() {

        Async.forEachFuture(Observable.just(1, 2, 3, 4, 5),
                new Action1<Integer>() {
                    @Override
                    public void call(Integer integer) {
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        newInfo(integer);

                    }
                });

    }


    private void newInfo(Integer integer){
        Log.e(TAG, "newInfo.................收到的数据是:" + integer+"..............转换成:"+integer*20);
    }


运行结果:



九、runAsync

任何时候都可以通过subscription的unsubscrip来停止订阅。rxjava-async模块还包含一个runAsync操作符。它很特殊,返回一个叫做StoppableObservable的特殊Observable。传递一个Action和一个SchedulerrunAsync,它返回一个使用这个Action产生数据的StoppableObservable。这个Action接受一个Observable和一个Subscription作为参数,它使用Subscription检查unsubscribed条件,一旦发现条件为真就立即停止发射数据。在任何时候你都可以使用unsubscribe方法手动停止一个StoppableObservable(这会同时取消订阅与这个StoppableObservable关联的Subscription)。

由于runAsync会立即调用Action并开始发射数据,在你创建StoppableObservable之后到你的观察者准备好接受数据之前这段时间里,可能会有一部分数据会丢失。如果这不符合你的要求,可以使用runAsync的一个变体,它也接受一个Subject参数,传递一个ReplaySubject给它,你可以获取其它丢失的数据了。在RxJava中还有一个版本的From操作符可以将Future转换为Observable,与start相似。

 //action所需要执行的线程
        Scheduler scheduler = Schedulers.newThread();
        Action2<? super Observer<? super Integer>, ? super Subscription> action = new Action2<Observer<? super Integer>, Subscription>() {
            @Override
            public void call(Observer<? super Integer> observer, Subscription subscription) {
               int i = 1;
                while (!subscription.isUnsubscribed()){
                    Log.e(TAG, "call................observer.onNext");
                    observer.onNext(i);
                    i += 1;
                    if(i == 4){
                        subscription.unsubscribe();
                        observer.onCompleted();
                    }
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

            }
        };

       StoppableObservable<Integer> stoppableObservable  =  Async.runAsync(scheduler, action);

        Subscriber<Integer> subscriber = new Subscriber<Integer>() {
            @Override
            public void onNext(Integer integer) {
                Log.e(TAG, "onNext................." + integer);
            }

            @Override
            public void onCompleted() {
                Log.e(TAG, "onCompleted.................");
            }

            @Override
            public void onError(Throwable e) {
                Log.e(TAG, "onError.....................");
            }
        };

        stoppableObservable.subscribe(subscriber);

运行结果:


`CompletableFuture.runAsync` 是 Java 中用于异步执行任务的方法,通常用于提高代码的并发性能和响应性。当你通过 `runAsync` 方法在一个 `CompletableFuture` 对象上执行一个任务时,这个任务会在一个新的线程中开始执行,并返回一个表示该任务完成状态的 `CompletableFuture`。 然而,`runAsync` 并不会自动保证异步操作的执行,如果在调用 `runAsync` 后,主线程很快地阻塞或者结束,那么原本预期在其他线程中运行的任务实际上可能会变成同步执行,因为没有其他的线程可以接替处理。这被称为“隐式同步”或“异步失效”。 导致这种情况的原因可能有: 1. 主线程在调用 `runAsync` 后立即等待某个结果,比如使用 `thenApply`、`thenAccept` 或其他阻塞操作。 2. 在调用 `runAsync` 后,没有正确设置回调或 Future 的完成监听,导致无法感知异步任务的结果。 3. `CompletableFuture` 的链式调用中,后续的操作没有正确地利用并发性质,使得整个链路变成了同步执行。 为了避免异步失效,你应该确保: - 不在 `runAsync` 后立即阻塞,而是使用非阻塞的方式处理结果(如 `.thenApply` 后跟一个无阻塞的回调)。 - 设置 Future 的完成监听器,以便在任务完成后得到通知。 - 尽量利用 `CompletableFuture` 提供的并发工具,例如 `.thenCompose` 和 `.join()` 的区别,确保在正确的地方处理并行性。 如果你需要确保任务确实异步执行,请考虑使用 `.submit` 方法,这样任务将被提交到线程池,而不是直接在当前线程执行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值