जिस तरह से मैं इसके बारे में सोचता हूं वह यह है कि आप flatMap
उस फ़ंक्शन का उपयोग करते हैं जो आप map()
रिटर्न के अंदर डालना चाहते थे Observable
। जिस स्थिति में आप अभी भी उपयोग करने की कोशिश कर सकते हैं map()
लेकिन यह अव्यावहारिक होगा। मुझे समझाने की कोशिश क्यों करते हैं।
अगर ऐसे मामले में आपने साथ रहना तय किया है map
, तो आपको ए Observable<Observable<Something>>
। आपके मामले में उदाहरण के लिए, यदि हमने एक काल्पनिक RxGson लाइब्रेरी का उपयोग किया है, जो कि Observable<String>
इसे toJson()
विधि से लौटाया है (इसके बजाय केवल a String
) यह इस तरह दिखेगा:
Observable.from(jsonFile).map(new Func1<File, Observable<String>>() {
@Override public Observable<String>> call(File file) {
return new RxGson().toJson(new FileReader(file), Object.class);
}
}); // you get Observable<Observable<String>> here
इस बिंदु पर इस subscribe()
तरह के अवलोकन के लिए यह बहुत मुश्किल होगा । इसके अंदर आपको एक ऐसा मिलेगा Observable<String>
जिसके लिए आपको फिर subscribe()
से मूल्य प्राप्त करने की आवश्यकता होगी । जो देखने में व्यावहारिक या अच्छा न हो।
तो इसे उपयोगी बनाने के लिए एक विचार "समतल" करना है, जो कि वेधशालाओं का अवलोकन है (आप यह देखना शुरू कर सकते हैं कि _flat_Map नाम कहां से आता है)। RxJava वेधशालाओं को समतल करने के लिए कुछ तरीके प्रदान करता है और सादगी के लिए यह मर्ज करना चाहता है कि हम क्या चाहते हैं। मर्ज मूल रूप से वेधशालाओं का एक गुच्छा लेता है और जब भी उनमें से कोई भी उत्सर्जन करता है तो उत्सर्जन करता है। (बहुत से लोगों का तर्क होगा कि स्विच एक बेहतर डिफ़ॉल्ट होगा। लेकिन यदि आप सिर्फ एक मूल्य का उत्सर्जन कर रहे हैं, तो यह वैसे भी मायने नहीं रखता है।)
तो हमारे पिछले स्निपेट में संशोधन करके हमें यह मिलेगा:
Observable.from(jsonFile).map(new Func1<File, Observable<String>>() {
@Override public Observable<String>> call(File file) {
return new RxGson().toJson(new FileReader(file), Object.class);
}
}).merge(); // you get Observable<String> here
यह बहुत अधिक उपयोगी है, क्योंकि इसकी सदस्यता (या मैपिंग, या फ़िल्टरिंग, या ...) आपको बस String
मूल्य मिलता है । (साथ ही, आप का ध्यान रखें, merge()
RxJava में ऐसा कोई वैरिएंट मौजूद नहीं है, लेकिन यदि आप मर्ज के विचार को समझते हैं तो मुझे उम्मीद है कि आप भी समझ जाएंगे कि यह कैसे काम करेगा।)
इसलिए मूल रूप से क्योंकि ऐसा merge()
शायद केवल तभी उपयोगी होना चाहिए जब यह map()
एक अवलोकनीय वापसी को सफल करता है और इसलिए आपको इसे बार-बार टाइप करने की आवश्यकता नहीं है, flatMap()
इसे शॉर्टहैंड के रूप में बनाया गया था। यह एक सामान्य map()
इच्छा के रूप में मानचित्रण फ़ंक्शन को लागू करता है , लेकिन बाद में लौटाए गए मूल्यों का उत्सर्जन करने के बजाय यह उन्हें "समतल" (या विलय) करता है।
यह सामान्य उपयोग का मामला है। यह एक कोडबेस में सबसे अधिक उपयोगी है जो आरएक्स एलोवर का उपयोग करता है और आपको कई तरीके मिलते हैं जो कि वेधशालाओं को लौटाते हैं, जिसे आप अन्य तरीकों से देखना चाहते हैं।
आपके उपयोग के मामले में यह उपयोगी होने के साथ-साथ होता है, क्योंकि map()
केवल उत्सर्जित एक मूल्य onNext()
को दूसरे उत्सर्जित में बदल सकता है onNext()
। लेकिन यह इसे कई मूल्यों में नहीं बदल सकता है, कोई मूल्य नहीं है या एक त्रुटि है। और जैसा कि akarnokd ने अपने उत्तर में लिखा है (और मन में है कि वह मुझसे ज्यादा चालाक है, शायद सामान्य तौर पर, लेकिन कम से कम जब यह RxJava की बात आती है) तो आपको अपने अपवादों को नहीं फेंकना चाहिए map()
। तो इसके बजाय आप उपयोग कर सकते हैं flatMap()
और
return Observable.just(value);
जब सब ठीक हो जाता है, लेकिन
return Observable.error(exception);
जब कुछ विफल होता है।
एक संपूर्ण स्निपेट के लिए उसका उत्तर देखें: https://stackoverflow.com/a/30330772/1402641
subscriber.onError()
आदि मैंने जितने भी उदाहरण देखे हैं उनमें सभी तरह की त्रुटियां हैं। क्या इससे कोई फर्क नहीं पड़ता?