Observable.zip
zip函数允许你传入多个请求,然后合并出另外的结果传出来,普通的用法就不多说了,网上一堆介绍的
然后做项目时有个疑问点,Observable.zip如果传入一个列表,合并列表里的所有请求的时候,请求从网络返回回来的顺序是未知的,那么我们subcribe订阅的数组是否会按传入时的顺序给到我们来处理呢。于是做了以下实验:
Integer[] skuSerials={1,2,3,4,5};
ArrayList<Observable<Integer>> requestList=new ArrayList<>();
for(int i=0;i<skuSerials.length;i++){
int finalI = i;
Observable<Integer> observable=Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter){
try {
Thread.sleep((5- finalI)*1000);
emitter.onNext(skuSerials[finalI]);
Log.e("log",finalI+"::"+Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).subscribeOn(Schedulers.io())
.subscribeOn(AndroidSchedulers.mainThread())
.observeOn(AndroidSchedulers.mainThread());
requestList.add(observable);
}
Observable.zip(requestList, new Function<Object[], Object>() {
@Override
public Object apply(Object[] objects) {
return objects;
}
}).subscribe(new Consumer<Object>() {
@Override
public void accept(Object o) throws Exception {
Object[] obs= (Object[]) o;
for(Object integer:obs){
Log.e("log",""+integer);
}
}
});
根据1~5的数组传入,并且创建1~5的请求,传入1的时候延迟5s,传入2的时候延迟4s…,以此来模拟网络请求,并且打印每个请求的线程名,正常来说5的请求应该是最先执行完的,但是它在list的顺序是放在最后的。最后我们zip这5个请求,并且打印传回来的Object[],结果如下:
结果和我们预期的一样,就是列表最后的请求,最先执行完,并且全部执行完毕后,才会触发subscribe的onNext()函数,然后回来的Object[]对象,存储的顺序也是按我们传入的列表那样是1~5顺序的结果。
如果我们当i=3的时候,调用emitter.onError()函数表示第三个请求出现了网络异常,修改代码如下:
Integer[] skuSerials={1,2,3,4,5};
ArrayList<Observable<Integer>> requestList=new ArrayList<>();
for(int i=0;i<skuSerials.length;i++){
int finalI = i;
Observable<Integer> observable=Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter){
try {
Thread.sleep((5- finalI)*1000);
emitter.onNext(skuSerials[finalI]);
Log.e("log",finalI+"::"+Thread.currentThread().getName());
if(finalI==3) emitter.onError(new Exception());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).subscribeOn(Schedulers.io())
.subscribeOn(AndroidSchedulers.mainThread())
.observeOn(AndroidSchedulers.mainThread());
requestList.add(observable);
}
Observable.zip(requestList, new Function<Object[], Object>() {
@Override
public Object apply(Object[] objects) {
return objects;
}
}).subscribe(new Observer<Object>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Object o) {
Object[] obs= (Object[]) o;
for(Object integer:obs){
Log.e("log",""+integer);
}
}
@Override
public void onError(Throwable e) {
Log.e("log","error");
}
@Override
public void onComplete() {
}
});
执行代码,打印log如下:
可以看到,当执行到第3个请求的时候,就抛出错误了,后面的请求也不执行了。