10

私は Observable で Retrofit を使用しており、Observable を連鎖させたいと考えています。はタスクを実行する Observable を返すため、通常はmap()またはのような関数でうまく機能します。ただし、この場合、次のことを行う必要があります。flatMap()api

  1. からの getKey()api
  2. 返されたキーを別のライブラリで使用Fooし、コールバックが呼び出されるのを待ちます。
  3. コールバックが戻ったら、結果を に送信しますapi

これを単一の連鎖呼び出しにしたいので、一度登録するだけで済みます。merge()またはjoin()または何かを使用できると思いますが、コールバックを処理するための最良のアプローチが何であるかはわかりませんでした。

これを改善する方法はありますか?これは私がこれまでに持っているものです:

api.getKey().subscribe(new Action1<String>() {
   @Override
   public void call(String key) {
      Foo foo = new Foo();
      foo.setAwesomeCallback(new AwesomeCallback() {
         @Override
         public void onAwesomeReady(String awesome) {
            api.sendAwesome(awesome)
                    .subscribe(new Action1<Void>() {
                       @Override
                       public void call(Void aVoid) {
                           handleAwesomeSent();
                       }
                    });
         }
      });
      foo.makeAwesome();
   }
});
4

3 に答える 3

4

PublishSubject を使用して、コールバック ベースの API をオブザーバブルに変換する必要があります。

そのようなことを試してください(テストされていません):

api.getKey().flatMap(new Func1<String, Observable<String>>() {
   @Override
   public Observable<String> call(String key) {
      Foo foo = new Foo();
      PublishSubject<String> subject = PublishSubject.create();
      foo.setAwesomeCallback(new AwesomeCallback() {
         @Override
         public void onAwesomeReady(String awesome) {
            subject.onNext(awesome);
            subject.onComplete();
         }
      });
      foo.makeAwesome();

      return subject;
   }
}).flatMap(new Func1<String, Observable<String>>() {
   @Override
   public Observable<String> call(String awesome) {
       return sendAwesome(awesome);
   }
}).subscribe(new Action1<Void>() {
    @Override
    public void call(Void aVoid) {
        handleAwesomeSent();
    }
});
于 2015-04-16T15:48:32.750 に答える
1
Api api = new Api() {
  @Override Single<String> getKey() {
    return Single.just("apiKey");
  }
};

api.getKey()
    .flatMap(key -> Single.<String>create( singleSubscriber -> {
        Foo foo = new Foo();
        foo.setAwesomeCallback(awesome -> {
          try { singleSubscriber.onSuccess(awesome);}
          catch (Exception e) { singleSubscriber.onError(e); }
        });
        foo.makeAwesome();
    }))
    .flatMapCompletable(
        awesome -> Completable.create(completableSubscriber -> {
          try {
            sendAwesome(awesome);
            completableSubscriber.onCompleted();
          } catch (Exception e) { completableSubscriber.onError(e); }
        }))
    .subscribe(this::handleAwesomeSent, throwable -> { });

完全な匿名クラスの例については、要点を参照してください

この実装は、タイプ セーフ/固有でありながら、SingleCompletableタイプを とともに使用することにより、david.mihola の回答を適応させます。flatMapCompletable()

于 2016-08-26T00:18:10.513 に答える