多次 API 调用以创建对象
Multiple API calls to create object
比方说,我有一个 class:
public class NI {
private int id;
@SerializedName("date")
private String created_at;
private String slug;
private String type;
private String link;
private WPTitle title;
private WPContent content;
private WPExcerpt excerpt;
@SerializedName("author")
private int authorId;
private int featured_media;
private WPMedia media;
List<Integer> categories;
}
还有一个class:
public class WPMedia {
private int id;
private String media_type;
private String mime_type;
private String source_url;
}
问题是 WPMedia
需要根据 int featured_media
的值进行单独的 API 调用。我将如何构建一个可观察链,以便它获得 NI
class 然后另一个获得 WPMedia
然后将其设置在对象上?
我正在使用 Retrofit 进行 API 调用,如下所示:
@GET("wp-json/wp/v2/posts")
Observable<ArrayList<NI>>getPostsObservableByCategory(@Query("categories") int category, @Query ("per_page") int limit, @Query("page") int skip);
@GET("wp-json/wp/v2/media/{id}")
Observable<WPMedia> getMediaObservable(@Path("id") int id);
我还不是很清楚你到底想要什么,但我会试一试。
我最初做的一个假设是,在 NI
上你有一个带有签名 public void setWPMedia(WPMedia media)
的 setter。鉴于您提供的两个 Retrofit 函数定义,我会说您执行以下操作:
getPostsObservableByCategory(...)
.flatMap(nis -> getMediaObservable(...)
.first()
.doOnNext(m -> nis.foreach(ni -> ni.setWPMedia(m)))
.map(m -> nis));
逐行检查:
getPostsObservableByCategory(...)
给你一个 Observable
发出 NI
个实例的列表。这些列表中每个 NI
的 media
字段可能已设置,也可能未设置。
getMediaObservable(...)
获取对应列表中每个元素需要设置的WPMedia
实例。
- 我限制
getMediaObservable
的发射次数为1次,否则NI
的字段会被设置多次,我想这不是很理想。如果 getMediaObservable(...)
function/implementation. 已保证这一点,则可以省略此行
- 设置一个字段被认为是副作用,所以我们在这里需要
doOnNext
,我们在其中遍历 NI
个实例的列表并将 WPMedia
字段设置为从 getMediaObservable
. 得到的那个
- 我假设你之后想要
NI
个实例的列表,所以我添加了一个 map
只是用那个列表替换了 m
。
希望对您有所帮助!
我给你找个演示!!!我想你可以这样做:
@GET("/token")
public Observable<String> getToken();
@GET("/user")
public Observable<User> getUser(@Query("token") String token, @Query("userId") String userId);
...
getToken()
.flatMap(new Func1<String, Observable<User>>() {
@Override
public Observable<User> onNext(String token) {
return getUser(token, userId);
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<User>() {
@Override
public void onNext(User user) {
userView.setUser(user);
}
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable error) {
// Error handling
...
}
});
比方说,我有一个 class:
public class NI {
private int id;
@SerializedName("date")
private String created_at;
private String slug;
private String type;
private String link;
private WPTitle title;
private WPContent content;
private WPExcerpt excerpt;
@SerializedName("author")
private int authorId;
private int featured_media;
private WPMedia media;
List<Integer> categories;
}
还有一个class:
public class WPMedia {
private int id;
private String media_type;
private String mime_type;
private String source_url;
}
问题是 WPMedia
需要根据 int featured_media
的值进行单独的 API 调用。我将如何构建一个可观察链,以便它获得 NI
class 然后另一个获得 WPMedia
然后将其设置在对象上?
我正在使用 Retrofit 进行 API 调用,如下所示:
@GET("wp-json/wp/v2/posts")
Observable<ArrayList<NI>>getPostsObservableByCategory(@Query("categories") int category, @Query ("per_page") int limit, @Query("page") int skip);
@GET("wp-json/wp/v2/media/{id}")
Observable<WPMedia> getMediaObservable(@Path("id") int id);
我还不是很清楚你到底想要什么,但我会试一试。
我最初做的一个假设是,在 NI
上你有一个带有签名 public void setWPMedia(WPMedia media)
的 setter。鉴于您提供的两个 Retrofit 函数定义,我会说您执行以下操作:
getPostsObservableByCategory(...)
.flatMap(nis -> getMediaObservable(...)
.first()
.doOnNext(m -> nis.foreach(ni -> ni.setWPMedia(m)))
.map(m -> nis));
逐行检查:
getPostsObservableByCategory(...)
给你一个Observable
发出NI
个实例的列表。这些列表中每个NI
的media
字段可能已设置,也可能未设置。getMediaObservable(...)
获取对应列表中每个元素需要设置的WPMedia
实例。- 我限制
getMediaObservable
的发射次数为1次,否则NI
的字段会被设置多次,我想这不是很理想。如果getMediaObservable(...)
function/implementation. 已保证这一点,则可以省略此行
- 设置一个字段被认为是副作用,所以我们在这里需要
doOnNext
,我们在其中遍历NI
个实例的列表并将WPMedia
字段设置为从getMediaObservable
. 得到的那个
- 我假设你之后想要
NI
个实例的列表,所以我添加了一个map
只是用那个列表替换了m
。
希望对您有所帮助!
我给你找个演示!!!我想你可以这样做:
@GET("/token")
public Observable<String> getToken();
@GET("/user")
public Observable<User> getUser(@Query("token") String token, @Query("userId") String userId);
...
getToken()
.flatMap(new Func1<String, Observable<User>>() {
@Override
public Observable<User> onNext(String token) {
return getUser(token, userId);
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<User>() {
@Override
public void onNext(User user) {
userView.setUser(user);
}
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable error) {
// Error handling
...
}
});