2016-11-17 3 views
6

मैं वर्तमान में एक सेवा को मारने की कोशिश कर रहा हूं और ग्राहकों को वापस लौटने से पहले ऑब्जेक्ट्स की एक सूची लौटा रहा हूं, मैं सूची में प्रत्येक ऑब्जेक्ट के लिए एक और सिंक्रोनस कॉल करना चाहता हूं ताकि एक लापता फ़ील्ड सेट करने के लिए एक और सेवा कॉल कर सके। । मैं सफलतापूर्वक सभी कॉल किए जा रहा हूं, लेकिन ग्राहक में लौटाई गई वस्तु में इस क्षेत्र में मुझे शून्य पर सेट करने की आवश्यकता है।सब्सक्राइबर पर लौटने से पहले मैं एक अवलोकन योग्य वस्तु को कैसे रोक सकता हूं और इसे आरएक्सजेवा में संशोधित कर सकता हूं?

उदाहरण सेवा::

rx.Observable<List<ExampleObject>> getExampleObject(); 
rx.Observable<MissingObject> getMissingObjectByFoo(@Path("foo") String foo); 

उदाहरण कक्षा: यहाँ मेरी कोड का एक उदाहरण है

public class ExampleObject { 
    String foo; 
    MissingObject bar; 

    public String getFoo() { 
     return this.foo; 
    } 

    public void setFoo(String value) { 
     this.foo = value; 
    } 

    public MissingObject getBar() { 
     return this.bar; 
    } 

    public void setBar(MissingObject value) { 
     this.bar = value; 
    } 
} 

उदाहरण कार्यान्वयन:

mService.getExampleObject().flatMap(new Func1<List<ExampleObject>, Observable<?>>() { 
      @Override 
      public Observable<List<ExampleObject>> call(List<ExampleObject> exampleObjects) { 
       for (ExampleObject entry : exampleObjects) { 
        String foo = entry.getFoo(); 
        mService.getMissingObjectByFoo(foo) 
          .subscribeOn(mScheduler.backgroundThread()) 
          .observeOn(mScheduler.mainThread()) 
          .subscribe(new Subscriber<MissingObject>() { 
         @Override 
         public void onCompleted() { 

         } 

         @Override 
         public void onError(Throwable e) { 

         } 

         @Override 
         public void onNext(MissingObject missingObject) { 
          entry.setBar(missingObject); 
         } 
        }); 
       } 
       return Observable.just(exampleObjects); 
      }; 
+0

क्या आप 'flatMap' का उपयोग नहीं कर सकते? – njzk2

+0

मैं flatmap का उपयोग कर रहा हूं, लेकिन सूची ग्राहक को वापस लौटा है सभी MissingObject फ़ील्ड –

+0

के लिए शून्य है, आप कोड साफ़ करने के लिए RxJava का उपयोग करते समय रेट्रोलैब्डा का उपयोग कर सकते हैं। – aleksandrbel

उत्तर

3

आप zip ऑपरेटर के लिए देख रहे हैं,:: यह कुछ मैं से बचने की कोशिश है, लेकिन यहां यह वैसे भी है Zip Operator। मुझे लगता है कि आप अपने कॉल के सभी के एक ज़िप के flatmap चाहते हैं, इसलिए, कुछ इस तरह:

mService.getExampleObject().flatMap(new Func1<List<ExampleObject>, Observable<ExampleObject>>() { 
     @Override 
     public Observable<List<ExampleObject>> call(List<ExampleObject> exampleObjects) { 
      List<Observable<ExampleObject>> allTheObservables = new ArrayList<Observable<ExampleObject>>(); 
      for (ExampleObject entry : exampleObjects) { 
       allTheObservables.add(mService.getMissingObjectByFoo(foo).map(new Func1<MissingObject, ExampleObject>() { 
        @Override 
        public ExampleObject call(MissingObject missingObject) { 
         return entry.setBar(missingObject); 
        } 
       })); 
      } 
      return Observable.zip(allTheObservables, new FuncN<ExampleObject>() { 
       @Override 
       public ExampleObject call(ExampleObject... args) { 
        return Arrays.asList(args); 
       } 
      }); 
     } 
    }); 

और मामले वह काम नहीं करता, या वाक्य रचना मुद्दे हैं में, यहाँ एक ठोस उदाहरण है, का उपयोग करते हुए GitHub एपीआई:

service.getContributorsObservable("square", "dagger") 
     .flatMap(new Func1<List<Contributor>, Observable<List<String>>>() { 
      @Override 
      public Observable<List<String>> call(List<Contributor> contributors) { 
       List<Observable<String>> allTheObservables = new ArrayList<>(contributors.size()); 
       for (final Contributor contributor : contributors) { 
        allTheObservables.add(service.getContributorsObservable(contributor.login).map(new Func1<User, String>() { 

         @Override 
         public String call(User user) { 
          return contributor.login + " is " + user.name; 
         } 
        })); 
       } 
       return Observable.zip(allTheObservables, new FuncN<List<String>>() { 
        @Override 
        public List<String> call(Object... args) { 
         return Arrays.asList((String[]) args); 
        } 
       }); 
      } 
     }); 

ध्यान रखें कि इस n + 1 नेटवर्क कॉल, ExampleObject रों की सूची के लिए 1, कर देगा रखें और उसके बाद 1 उस सूची में ExampleObject प्रति। यदि यह पर संभव है, तो मैं दृढ़ता से सुझाव देता हूं कि आप एपीआई पक्ष के बारे में जानकारी लुकअप प्राप्त करने के लिए एपीआई के रखरखाव से बात करें। बस पता है कि यह कुछ बैंडविड्थ का उपयोग करने जा रहा है!

3

प्रविष्टि अद्यतन करने के लिए अपने मध्यस्थ कॉल क्योंकि असीमित है, मुझे नहीं लगता कि आप List<ExampleObject> का उपयोग करने के लिए चिपक सकते हैं, लेकिन इसके बजाय Observable से सीधे ExampleObject हेरफेर:

mService.getExampleObject() 
    // Spread the list 
    .flatMap(list -> Observable.from(list)) 
    // Update your object 
    // Here we zip the object with the missing object, 
    // so that when the missing object is obtained, 
    // we update the entry and emit it. 
    .flatMap(entry -> Observable.zip(
      Observable.just(entry), 
      mDocsService.getMissingObjectByFoo(entry.getFoo()), 
      (entry, missingObject) -> { 
       entry.setBar(missingObject); 
       return entry; 
      }) 
    ) 
    // if you really want a map after all 
    .toList(); 

साइड नोट:

आप जिप को छोड़ सकते हैं अगर आप एक बाहरी चर (प्रवेश) पर निर्भर map में समारोह होने के साथ ठीक कर रहे हैं। यहां दिए गए अनुसार

.flatMap(entry -> mDocsService.getMissingObjectByFoo(entry.getFoo()) 
            .map(missingObject -> { 
             entry.setBar(missingObject); 
             return entry; 
            }) 
    ) 
संबंधित मुद्दे

 संबंधित मुद्दे