RxJava में फ्लैटमैप और स्विचमैप के बीच अंतर क्या है?


149

स्विचमैप की rxjava डॉक्टर परिभाषा बल्कि अस्पष्ट है और यह फ्लैटमैप के रूप में एक ही पृष्ठ से लिंक करता है। दोनों ऑपरेटरों के बीच क्या अंतर है?


1
इसके बारे में उसी पृष्ठ से लिंक होता है जैसे फ्लैटमैप । यह वास्तव में सच है। लेकिन भाषा-विशिष्ट सूचना अनुभाग पर जाएं और दिलचस्प ऑपरेटर खोलें। मुझे लगता है कि यह टीओसी से स्वचालित रूप से किया जाना चाहिए, लेकिन ... इसके अलावा आप उसी तस्वीर को जावदॉक में देख सकते हैं ।
रुस्लान Stelmachenko

जवाबों:


180

प्रलेखन के अनुसार ( http://reactivex.io/documentation/operators/flatmap.html )

की switchMapतरह है flatMap, लेकिन यह केवल नए ऑब्जर्वेबल से आइटम का उत्सर्जन करेगा जब तक कि एक नई घटना स्रोत से अवलोकन योग्य नहीं होती है।

संगमरमर का चित्र इसे अच्छी तरह से दिखाता है। रेखाचित्र में अंतर पर ध्यान दें:

में switchMapदूसरा मूल उत्सर्जन ( हरे संगमरमर ) अपनी दूसरी उत्सर्जन नहीं मैप किए गए उत्सर्जन ( हरे वर्ग ), तीसरे के बाद से मूल उत्सर्जन ( नीले संगमरमर ) शुरू हो गया है और पहले से ही अपनी पहली उत्सर्जित मैप किया उत्सर्जन ( नीला हीरा )। दूसरे शब्दों में, केवल दो मैप किए गए हरे उत्सर्जन में से पहला होता है; कोई भी हरे रंग का वर्ग उत्सर्जित नहीं होता है क्योंकि नीला हीरा उसे हरा देता है।

में flatMap, सभी मैप किए गए परिणाम उत्सर्जित होंगे, भले ही वे "बासी" हों। दूसरे शब्दों में, मैप किए गए हरे उत्सर्जन का पहला और दूसरा दोनों होता है - एक हरे रंग का वर्ग उत्सर्जित होता है (यदि वे लगातार मानचित्र कार्य करते हैं; चूंकि वे नहीं किया था, तो आप दूसरे हरे हीरे को देखते हैं , भले ही यह उत्सर्जित हो। पहले नीला हीरा)

switchMap अगर मूल ऑब्जर्वेबल कुछ नया उत्सर्जित करता है, तो स्विचपैप में, पिछले उत्सर्जन अब मैप किए गए वेधशाला का उत्पादन नहीं करते हैं;  यह बासी परिणामों से बचने का एक प्रभावी तरीका है

flatMap

अगर मूल ऑब्जर्वेबल कुछ नया उत्सर्जित करता है, तो स्विचपैप में, पिछले उत्सर्जन अब मैप किए गए वेधशाला का उत्पादन नहीं करते हैं;  यह एवियो बासी परिणामों के लिए एक प्रभावी तरीका है


4
धन्यवाद, आरेख बहुत मददगार है। क्या आप एक वास्तविक विश्व उदाहरण जानते हैं कि स्विचपाइप का उपयोग कहां किया जाएगा?
जूलियन गो

1
@ जूलियनगो यहां एक उदाहरण है: github.com/samuelgruetter/rx-playground/blob/master/… यह उपयोग करता है .map(func).switch, लेकिन यह वैसा ही है .switchMap(func)
शमूएल ग्रेटर

2
बस अगर किसी को अभी भी स्विचपाइप की वास्तविक दुनिया के उदाहरण की आवश्यकता है, तो वह इस लिंक लिंक का पालन कर सकता है और यह समझ जाएगा कि फ़्लैटबॉल के बजाय स्विचथैप का उपयोग कब करना है।
हरमनोविच

2
उदाहरण के लिए बेन Lesh से RxJs5 का उपयोग करते हुए स्विचपॉइंट का उपयोग करें - मिनट 25-26 यहां देखें - youtube.com/watch?v=3LKMwkuK0ZE मेरे लिए, फ्लैटमैप पहले ही समझ में आ गया था ...
arcseldon

7
संगमरमर आरेख यह अच्छी तरह से दिखाता है? क्या? मुझे लगता है कि अगर आप पहले से ही स्विचमैप को समझते हैं।
हेलजेट

166

"त्वरित खोज" को लागू करते समय मैं इस पर आया था - जब एक पाठ बॉक्स में उपयोगकर्ता प्रकार, और परिणाम प्रत्येक कुंजी स्ट्रोक के साथ वास्तविक समय के पास दिखाई देते हैं। समाधान लगता है:

  1. एक विषय है, जैसे कि पब्लिशिंगसबजेक्ट ऑफ स्ट्रिंग
  2. पाठ बॉक्स परिवर्तन कॉलबैक में, .onNext (पाठ) को आमंत्रित करें
  3. दर सीमा सर्वर प्रश्नों के लिए .Debounce फ़िल्टर लागू करें
  4. सर्वर क्वेरी लागू करने के लिए .switchMap - खोज शब्द लेने और SearchResponse के अवलोकन को वापस करने के लिए
  5. एक तरीका है जो SearchResponse उपभोग करता है और UI को अद्यतन करता है के साथ लागू करें।

फ्लैटपाइप के साथ, खोज परिणाम बासी हो सकते हैं, क्योंकि खोज प्रतिक्रियाएं ऑर्डर से वापस आ सकती हैं। इसे ठीक करने के लिए, स्विचपॉइंट का उपयोग किया जाना चाहिए, क्योंकि यह सुनिश्चित करता है कि एक नया देखने के बाद एक पुरानी अवलोकन योग्य सदस्यता समाप्त कर दी जाए।

इसलिए, सारांश में, सभी परिणाम के समय, उनके समय की परवाह किए बिना, फ्लैटपाउट का उपयोग किया जाना चाहिए और अंतिम ऑब्जर्वेबल मामले से केवल परिणाम होने पर स्विचेप का उपयोग किया जाना चाहिए।



95

तुलना और इसके साथ तुलना के बिना कोई भी फ्लैटपाइप चर्चा पूर्ण नहीं है switchMap, concatMapऔरconcatMapEager

ये सभी विधियाँ Func1धारा को रूपांतरित करती Observableहैं जो तब उत्सर्जित होती हैं; अंतर तब होता है जब लौटे हुए Observableएस को सब्सक्राइब और अनसब्सक्राइब किया जाता है, और यदि उन के उत्सर्जन Observableको ____Mapसंचालक द्वारा विचाराधीन उत्सर्जित किया जाता है ।

  • flatMapObservableजितना संभव हो उतने उत्सर्जित सदस्यों की सदस्यता लेता है। (यह एक प्लेटफ़ॉर्म आश्रित संख्या है। उदाहरण के लिए एंड्रॉइड पर एक कम संख्या) इसका उपयोग तब करें जब ऑर्डर महत्वपूर्ण न हो, और आप ASAP उत्सर्जन चाहते हैं।
  • concatMapपहले वाले को सब्सक्राइब करता है Observableऔर Observableपिछले वाले को पूरा होने पर ही अगले को सब्सक्राइब करता है। जब ऑर्डर महत्वपूर्ण हो और आप संसाधनों का संरक्षण करना चाहते हैं तो इसका उपयोग करें। एक आदर्श उदाहरण पहले कैश की जांच करके एक नेटवर्क कॉल को समाप्त करना है। आम तौर पर .first()या .takeFirst()अनावश्यक काम करने से बचने के लिए इसका अनुसरण किया जा सकता है ।

    http://blog.danlew.net/2015/06/22/loading-data-from-multiple-sources-with-rxjava/

  • concatMapEagerबहुत समान काम करता है, लेकिन जितना संभव हो सके (प्लेटफ़ॉर्म आश्रित) के लिए सब्सक्राइब करता है, लेकिन केवल एक बार पिछले Observableपूरा होने के बाद ही उत्सर्जन करेगा । बिल्कुल सही जब आपके पास बहुत अधिक समानांतर-प्रसंस्करण होता है जिसे करने की आवश्यकता होती है, लेकिन (सपाट नक्शा के विपरीत) आप मूल आदेश को बनाए रखना चाहते हैं।

  • switchMapपिछले के लिए सदस्यता लेंगे Observableयह पिछले सभी से मुठभेड़ों और सदस्यता समाप्त Observable। यह खोज-सुझावों जैसे मामलों के लिए एकदम सही है: एक बार जब उपयोगकर्ता ने अपनी खोज क्वेरी बदल दी है, तो पुराना अनुरोध किसी भी हित का नहीं रह गया है, इसलिए यह सदस्यता समाप्त कर दिया गया है, और एक अच्छा व्यवहार किया गया एपी एंड-पॉइंट नेटवर्क अनुरोध को रद्द कर देगा।

यदि आप Observableएस वापस कर रहे हैं जो subscribeOnएक और धागा नहीं है , तो उपरोक्त सभी तरीके समान व्यवहार कर सकते हैं। दिलचस्प और उपयोगी व्यवहार तब सामने आता है जब आप नेस्टेड Observableएस को अपने स्वयं के धागे पर कार्य करने की अनुमति देते हैं । फिर आप समानांतर प्रसंस्करण से बहुत सारे लाभ प्राप्त कर सकते हैं, और समझदारी से सदस्यता समाप्त कर सकते हैं या सदस्यता नहीं ले सकते हैं Observableजो आपके Subscriberएस की जरूरत नहीं है

  • ambब्याज की भी हो सकती है। किसी भी संख्या को देखते हुए Observableयह उन्हीं वस्तुओं का उत्सर्जन करता है जो सबसे पहले Observableकिसी भी चीज का उत्सर्जन करती हैं। यह उपयोगी हो सकता है जब आपके पास कई स्रोत हैं जो एक ही चीज़ को वापस कर सकते हैं / चाहिए और आप प्रदर्शन चाहते हैं। छँटाई की तरह, आप ambमर्ज-सॉर्ट के साथ एक त्वरित-सॉर्ट कर सकते हैं और जो भी तेज़ था उसका उपयोग करें।

1
If you are returning Observables that don't subscribeOn another thread, all of the above methods may behave much the same.- switchMap vs flatMapइससे पहले मैंने जो भी स्पष्टीकरण दिया, वह इस महत्वपूर्ण पहलू से चूक गया, अब सब कुछ स्पष्ट है। धन्यवाद।
एंडी रेस

55

switchMap एक बार बुलाया गया था flatMapLatest RxJS 4 में।

यह मूल रूप से पिछले एक से नवीनतम ऑब्जर्वेबल और अनसब्सक्राइब से घटनाओं पर गुजरता है ।


@EpicPandaForce हालाँकि यह CombLLestest के साथ असंगत है, जो कि जब भी कोई स्रोत अवलोकन योग्य होता है (एक बार उत्सर्जन नहीं होता है) नवीनतम मूल्यों का उत्सर्जन करता है।
माइकल फ्राई

2
आंशिक रूप से इसका कारण स्विचपॉट कहा जाता है क्योंकि आप इस ऑपरेटर को o.map (...) स्विच () का उपयोग करके स्वयं कार्यान्वित कर सकते हैं। हालांकि तब मुझे लगता है कि यह मैपविच होगा, जो इतनी आसानी से जीभ को रोल नहीं करता है।
Niall Connaughton

7

मानचित्र, FlatMap, ConcatMap और SwitchMap एक समारोह या संशोधित डेटा एक नमूदार द्वारा उत्सर्जित लागू होता है।

  • मानचित्र एक स्रोत द्वारा उत्सर्जित प्रत्येक वस्तु को संशोधित करता है और संशोधित वस्तु का उत्सर्जन करता है।

  • FlatMap, SwitchMap और ConcatMap प्रत्येक उत्सर्जित आइटम पर एक फ़ंक्शन भी लागू करता है, लेकिन संशोधित आइटम को वापस करने के बजाय, यह ऑब्जर्वेबल को स्वयं वापस करता है जो डेटा को फिर से उत्सर्जित कर सकता है।

  • FlatMap और ConcatMap काम बहुत ज्यादा एक ही है। वे कई वेधशालाओं द्वारा उत्सर्जित वस्तुओं को मर्ज करते हैं और एक एकल वेधशाला को लौटाते हैं।

  • FlatMap और ConcatMap के बीच का अंतर वह क्रम है जिसमें आइटम उत्सर्जित होते हैं।
  • फ्लैटमैप उत्सर्जित करते समय वस्तुओं को इंटरलेव कर सकता है अर्थात उत्सर्जित वस्तुओं के ऑर्डर को बनाए नहीं रखा जाता है।
  • ConcatMap वस्तुओं के क्रम को संरक्षित करता है। लेकिन ConcatMap का मुख्य नुकसान यह है कि उसे अपने काम को पूरा करने के लिए प्रत्येक अवलोकन के लिए इंतजार करना पड़ता है, इसलिए अतुल्यकालिक को बनाए नहीं रखा जाता है।
  • SwitchMap से थोड़ा अलग है FlatMap और ConcatMapSwitchMap पिछले स्रोत से सदस्यता भी समाप्त हो नमूदार जब भी नया आइटम उत्सर्जक, इस प्रकार हमेशा वर्तमान प्रत्यक्ष से आइटम उत्सर्जक शुरू कर दिया।

1

यदि आप एक उदाहरण कोड की तलाश में हैं

/**
 * We switch from original item to a new observable just using switchMap.
 * It´s a way to replace the Observable instead just the item as map does
 * Emitted:Person{name='Pablo', age=0, sex='no_sex'}
 */
@Test
public void testSwitchMap() {
    Observable.just(new Person("Pablo", 34, "male"))
              .switchMap(person -> Observable.just(new Person("Pablo", 0, "no_sex")))
              .subscribe(System.out::println);

}

आप यहां और उदाहरण देख सकते हैं https://github.com/politrons/reactive


4
लेकिन आप स्विचपैन की प्रमुख विशेषता को याद करते हैं जो इसे फ्लैटपाइप से अलग करता है - केवल सबसे हाल ही में देखने योग्य मामले, जबकि पिछले वाले से अनसब्सक्राइब करना।
अर्टेम नोविकोव

3
इस उदाहरण में, जब आप की जगह switchMapके साथ flatMapयह बिल्कुल वैसा ही काम करेंगे।
पायोत्र विटचन

1

यहाँ एक और है - 101 लाइन लंबी मिसाल । जो मेरे लिए बात समझाती है।

जैसा कहा गया था: यह अंतिम अवलोकन योग्य है (यदि आप करेंगे तो सबसे धीमा) और बाकी की अनदेखी करता है।

नतीजतन:

Time | scheduler | state
----------------------------
0    | main      | Starting
84   | main      | Created
103  | main      | Subscribed
118  | Sched-C-0 | Going to emmit: A
119  | Sched-C-1 | Going to emmit: B
119  | Sched-C-0 | Sleep for 1 seconds for A
119  | Sched-C-1 | Sleep for 2 seconds for B
1123 | Sched-C-0 | Emitted (A) in 1000 milliseconds
2122 | Sched-C-1 | Emitted (B) in 2000 milliseconds
2128 | Sched-C-1 | Got B processed
2128 | Sched-C-1 | Completed

आप देखते हैं कि ए को नजरअंदाज कर दिया गया है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.