rxjava2 中 zip 函数的问题

Problems with zip function in rxjava2

zip 函数似乎不执行 anything.The 带有 TAG INSIDE 的请求日志打印出可观察对象但为空 OUTSIDE.In zip 函数 LOG 调用不执行任何操作。 getPosts returns id 列表。 我是 Android 的初学者,所以也许我对 Rxjava 的理解还不够,但显然这是我最好的 solution.Essentially、getPosts returns id 列表应该用于在 getStory 中编写进一步的请求。如果有更简单的我很想听到 it.Thanks。

主要活动

package com.example.hackernews;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.RecyclerView;

import android.annotation.SuppressLint;
import android.os.Bundle;
import android.util.Log;

import java.util.ArrayList;
import java.util.List;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

import static java.lang.Math.min;

public class MainActivity extends AppCompatActivity {
    private RecyclerView mRecyclerView;
    private RecyclerView.Adapter mAdapter;
    private RecyclerView.LayoutManager mLayoutManager;
    private  List<DataResponse> dataResponses;
    private Observable<List<Integer>> ids;
    private List<Observable<DataResponse>> requests = new ArrayList<>();

    @SuppressLint("CheckResult")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);




//        mRecyclerView = findViewById(R.id.recyclerView);
//        mRecyclerView.setHasFixedSize(true);
//        mLayoutManager = new LinearLayoutManager(getApplicationContext());
//        mRecyclerView.setLayoutManager(mLayoutManager);



        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        OkHttpClient client = new OkHttpClient.Builder()
                .addInterceptor(interceptor)
                .build();

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://hacker-news.firebaseio.com/v0/")
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .client(client)
                .build();

        HackerNewsApi hackerNewsApi = retrofit.create(HackerNewsApi.class);

        ids = hackerNewsApi.getPosts();

        ids.subscribeOn(Schedulers.io())
                .observeOn(Schedulers.io())
                .subscribe(id -> {
                    for (Integer i : id) {
                        requests.add(hackerNewsApi.getStory(i));
                    }
                    Log.e("onSubscribe", "INSIDE " + requests);
                }, Throwable::printStackTrace);
        Log.e("onSubscribe", "OUTSIDE " + requests);

        Observable.zip(
                requests,
                new Function<Object[], Object>() {
                    @Override
                    public Object apply(Object[] objects) throws Exception {
                        // Objects[] is an array of combined results of completed requests

                        Log.e("onSubscribe", "YOUR OBJECTS ARE HERE: " + objects);
                        // do something with those results and emit new event
                        return new Object();
                    }
                })
                // After all requests had been performed the next observer will receive the Object, returned from Function
                .subscribe(
                        // Will be triggered if all requests will end successfully (4xx and 5xx also are successful requests too)
                        new Consumer<Object>() {
                            @Override
                            public void accept(Object o) throws Exception {
                                //Do something on successful completion of all requests
                                Log.e("onSubscribe", "YOUR OBJECTS ARE HERE: " + o);
                            }
                        },

                        // Will be triggered if any error during requests will happen
                        new Consumer<Throwable>() {
                            @Override
                            public void accept(Throwable e) throws Exception {
                                //Do something on error completion of requests
                            }
                        }
                );


//            mRecyclerView = findViewById(R.id.recyclerView);
//            mRecyclerView.setHasFixedSize(true);
//            mLayoutManager = new LinearLayoutManager(this);
//            Log.e("onSubscribe", "YOUR DATA IS HERE: " + dataResponses);
//            mAdapter = new ExampleAdapter(dataResponses);
//
//
//            mRecyclerView.setLayoutManager(mLayoutManager);
//            mRecyclerView.setAdapter(mAdapter);


    }

}

HackerNewsApi

package com.example.hackernews;

import java.util.List;

import io.reactivex.Observable;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Path;

public interface HackerNewsApi {

    @GET("askstories.json?print=pretty")
    Observable<List<Integer>> getPosts();

    @GET("item/{id}.json?print=pretty")
    Observable<DataResponse> getStory(@Path("id") Integer id);
}

您创建了一个故事列表,在后台检索可观察对象,并同时尝试使用在主线程上构建的列表。

为什么不像这样简单地合成 getPosts()

 hackerNewsApi.getPosts()
 .subscribeOn(Schedulers.io())
 .flatMapIterable(posts -> posts)
 .flatMap(post -> hackerNewsApi.getStory(post))
 .toList()
 .observeOn(AndroidSchedulers.mainThread())
 .subscribe(allStories -> { /* ... */ }, error -> { /* ... */ });

flatMapIterable 展开您的初始帖子列表,然后 toList 按某种顺序重新组合它们。