क्या फ्लक्स स्टोर, या एक्शन (या दोनों) बाहरी सेवाओं को छूना चाहिए?


122

क्या दुकानों को अपनी स्थिति बनाए रखनी चाहिए और ऐसा करने में नेटवर्क और डेटा स्टोरेज सेवाओं को कॉल करने की क्षमता होनी चाहिए ... जिस स्थिति में कार्रवाई केवल मूक संदेश भेजने वाले हैं,

-या-

... क्या भंडार क्रियाओं से अपरिवर्तनीय डेटा प्राप्त करने वाले (और कार्य करने वाले) बाहरी स्रोतों के बीच डेटा प्राप्त करने / भेजने वाले होने चाहिए? इस उदाहरण में स्टोर दृश्य-मॉडल के रूप में कार्य करेगा और उन्हें एकत्रित / फ़िल्टर करने में सक्षम होगा कार्रवाई द्वारा खिलाए गए अपरिवर्तनीय डेटा पर अपना स्वयं का राज्य आधार स्थापित करने से पहले डेटा।

यह मुझे लगता है कि यह एक या दूसरे (दोनों के मिश्रण के बजाय) होना चाहिए। यदि ऐसा है, तो क्यों एक दूसरे पर पसंदीदा / अनुशंसित है?


2
यह पोस्ट code-experience.com/…
Markus-ipse

फ्लक्स पैटर्न के विभिन्न कार्यान्वयनों का मूल्यांकन करने वालों के लिए, मैं अत्यधिक Redux github.com/rackt/redux स्टोर्स पर एक नज़र डालने की सलाह दूंगा , जिन्हें वर्तमान राज्य में लेने वाले शुद्ध कार्यों के रूप में लागू किया जाता है और उस राज्य के एक नए संस्करण का उत्सर्जन होता है। चूंकि वे शुद्ध कार्य करते हैं और नेटवर्क या भंडारण सेवाओं को आपके हाथों से लिया गया है या नहीं, इस सवाल का जवाब है: वे नहीं कर सकते।
प्लैक्सडान

जवाबों:


151

मैंने देखा है कि फ्लक्स पैटर्न ने दोनों तरीकों को लागू किया है, और दोनों खुद को करने के बाद (शुरू में पूर्व दृष्टिकोण के साथ जा रहे हैं), मेरा मानना ​​है कि दुकानों को कार्रवाई से डेटा प्राप्त करने वालों को गूंगा होना चाहिए, और लेखन के अतुल्यकालिक प्रसंस्करण को लाइव में रहना चाहिए एक्शन क्रिएटर्स। ( Async रीड्स को अलग तरीके से संभाला जा सकता है ।) मेरे अनुभव में, इसके महत्व के क्रम में कुछ लाभ हैं:

  1. आपके स्टोर पूरी तरह से सिंक्रोनस हो जाते हैं। इससे आपके स्टोर लॉजिक का अनुसरण करना बहुत आसान हो जाता है और परीक्षण करना बहुत आसान हो जाता है - बस किसी दिए गए राज्य के साथ एक स्टोर को तुरंत भेजें, इसे एक कार्रवाई भेजें, और यह देखने के लिए जांचें कि क्या राज्य अपेक्षित रूप से बदल गया है। इसके अलावा, फ्लक्स में मुख्य अवधारणाओं में से एक कैस्केडिंग डिस्पैच को रोकने और एक बार में कई डिस्पैच को रोकने के लिए है; जब आपके स्टोर अतुल्यकालिक प्रसंस्करण करते हैं तो यह करना बहुत मुश्किल होता है।

  2. सभी एक्शन प्रेषण एक्शन क्रिएटर्स से होते हैं। यदि आप अपने स्टोर में अतुल्यकालिक संचालन को संभालते हैं और आप अपने स्टोर के एक्शन हैंडलर को सिंक्रोनस रखना चाहते हैं (और आपको फ्लक्स सिंगल-डिस्पैच गारंटी प्राप्त करने के लिए चाहिए), तो आपके स्टोर्स को एसिंक्रोनस के जवाब में अतिरिक्त SUCCESS और फेल एक्शन की आवश्यकता होगी। प्रसंस्करण। इन प्रेषणों को एक्शन क्रिएटर्स में डालने के बजाय एक्शन क्रिएटर्स और स्टोर्स की नौकरियों को अलग करने में मदद करता है; इसके अलावा, आपको यह जानने के लिए अपने स्टोर लॉजिक के माध्यम से खुदाई करने की ज़रूरत नहीं है कि कार्रवाई कहाँ से भेजी जा रही है। इस मामले में एक विशिष्ट अतुल्यकालिक कार्रवाई कुछ इस तरह दिख सकती है ( dispatchफ्लक्स के स्वाद के आधार पर कॉल के सिंटैक्स को बदल दें ):

    someActionCreator: function(userId) {
      // Dispatch an action now so that stores that want
      // to optimistically update their state can do so.
      dispatch("SOME_ACTION", {userId: userId});
    
      // This example uses promises, but you can use Node-style
      // callbacks or whatever you want for error handling.
      SomeDataAccessLayer.doSomething(userId)
      .then(function(newData) {
        // Stores that optimistically updated may not do anything
        // with a "SUCCESS" action, but you might e.g. stop showing
        // a loading indicator, etc.
        dispatch("SOME_ACTION_SUCCESS", {userId: userId, newData: newData});
      }, function(error) {
        // Stores can roll back by watching for the error case.
        dispatch("SOME_ACTION_FAIL", {userId: userId, error: error});
      });
    }

    विभिन्न क्रियाओं में दोहराए जा सकने वाले तर्क को एक अलग मॉड्यूल में निकाला जाना चाहिए; इस उदाहरण में, वह मॉड्यूल होगा SomeDataAccessLayer, जो वास्तविक अजाक्स अनुरोध करने का काम करता है।

  3. आपको कम एक्शन क्रिएटर्स चाहिए। यह कम बड़ी बात नहीं है, लेकिन अच्छा है। जैसा कि # 2 में उल्लेख किया गया है, यदि आपके स्टोर में सिंक्रोनस एक्शन डिस्पैच हैंडलिंग (और उन्हें चाहिए) है, तो आपको एसिंक्रोनस ऑपरेशन के परिणामों को संभालने के लिए अतिरिक्त क्रियाओं को फायर करना होगा। एक्शन क्रिएटर्स में डिस्पैच करने का मतलब है कि एक ही एक्शन क्रिएटर एसिंक्रोनस डेटा एक्सेस के परिणाम को हैंडल करके सभी तीनों एक्शन टाइप्स को डिस्पैच कर सकता है।


15
मुझे लगता है कि वेब एपीआई कॉल (एक्शन क्रिएटर बनाम स्टोर) की उत्पत्ति क्या है, इस तथ्य से कम महत्वपूर्ण नहीं है कि सफलता / त्रुटि कॉलबैक एक कार्रवाई पैदा करे। तो डेटा प्रवाह तो हमेशा होता है: कार्रवाई -> डिस्पैचर -> स्टोर -> दृश्य।
फिशरदेबदेव

1
एपीआई मॉड्यूल के भीतर वास्तविक अनुरोध तर्क को बेहतर / परीक्षण करना आसान होगा? तो आपका एपीआई मॉड्यूल एक वादा वापस कर सकता है जिसे आप से भेजते हैं। कार्रवाई निर्माता केवल प्रारंभिक 'लंबित' कार्रवाई भेजने के बाद समाधान / असफलता पर आधारित प्रेषण करता है। सवाल यह है कि घटक इन 'घटनाओं' को कैसे सुनता है क्योंकि मुझे यकीन नहीं है कि अनुरोध राज्य को स्टोर करने के लिए मैप करना चाहिए।
बैकडेस्क

@backdesk ठीक यही है जो मैं ऊपर दिए गए उदाहरण में करता हूं: प्रारंभिक लंबित कार्रवाई ( "SOME_ACTION") को भेजें , अनुरोध करने के लिए एक API का उपयोग करें ( SomeDataAccessLayer.doSomething(userId)) जो एक वादा लौटाता है, और दो .thenकार्यों में, अतिरिक्त कार्यों को भेजता है। यदि राज्य को राज्य की स्थिति के बारे में जानकारी प्राप्त करने की आवश्यकता है, तो राज्य को स्टोर करने के लिए (अधिक या कम) मानचित्र का अनुरोध कर सकते हैं। यह मानचित्र ऐप पर कैसा है (उदाहरण के लिए शायद प्रत्येक टिप्पणी में एक व्यक्तिगत त्रुटि स्थिति, एक ला फेसबुक, या शायद एक वैश्विक त्रुटि घटक है)
मिशेल टायली

@MichelleTilley "फ्लक्स में मुख्य अवधारणाओं में से एक कैस्केडिंग डिस्पैच को रोकने और एक बार में कई डिस्पैच को रोकने के लिए है; यह तब करना बहुत मुश्किल है जब आपके स्टोर एसिंक्रोनस प्रोसेसिंग करते हैं।" मेरे लिए यह एक महत्वपूर्ण बिंदु है। ख़ूब कहा है।

51

मैंने फेसबुक पर देवों को यह सवाल ट्वीट किया और मुझे बिल फिशर से मिला जवाब था:

जब यूआई के साथ उपयोगकर्ता की बातचीत का जवाब होता है, तो मैं ऐक्शन क्रिएटर तरीकों से एसिंक्स कॉल करूंगा।

लेकिन जब आपके पास एक टिकर या कोई अन्य गैर-मानव चालक होता है, तो स्टोर से एक कॉल बेहतर काम करता है।

महत्वपूर्ण बात यह है कि त्रुटि / सफलता कॉलबैक में एक कार्रवाई करना है ताकि डेटा हमेशा कार्रवाई के साथ उत्पन्न हो


जबकि यह समझ में आता है, किसी भी विचार क्यों a call from store works better when action triggers from non-human driver ?
शार्पकोड

@SharpCoder मुझे लगता है कि अगर आपके पास एक लाइव-टिकर या कुछ समान है, तो आपको वास्तव में एक कार्रवाई को फायर करने की आवश्यकता नहीं है और जब आप स्टोर से ऐसा करते हैं, तो आपको शायद कम कोड लिखना होगा, क्योंकि स्टोर तुरंत राज्य का उपयोग कर सकता है। और एक परिवर्तन का उत्सर्जन करें।
फ्लोरियन वेंडेलबोर्न

8

स्टोर को डेटा प्राप्त करने और घटकों को संकेत देने सहित सब कुछ करना चाहिए जो स्टोर के डेटा को अपडेट किया गया है। क्यों? क्योंकि क्रियाएं तब महत्वपूर्ण व्यवहार को प्रभावित किए बिना हल्के, डिस्पोजेबल और बदली जा सकती हैं। स्टोर में सभी महत्वपूर्ण व्यवहार और कार्यक्षमता होती है। यह व्यवहार के दोहराव को भी रोकता है जिसे अन्यथा दो समान लेकिन अलग-अलग कार्यों में कॉपी किया जाएगा। भंडार सत्य का (हैंडलिंग) का आपका एकल स्रोत हैं।

प्रत्येक फ्लक्स कार्यान्वयन में मैंने देखा है कि क्रियाएँ मूल रूप से घटना तार वस्तुओं में बदल जाती हैं, जैसे पारंपरिक रूप से आपके पास "एंकर: क्लिक" नामक एक घटना होगी, लेकिन फ़्लक्स में इसे एंकर के रूप में परिभाषित किया जाएगा। वे यहां तक ​​कि "गूंगा" भी हैं कि अधिकांश कार्यान्वयन में डिस्पैचर ऑब्जेक्ट्स हैं जो वास्तव में घटनाओं को स्टोर करने के लिए भेजते हैं जो सुन रहे हैं।

व्यक्तिगत रूप से मुझे फ्लक्स के रीफ्लक्स का कार्यान्वयन पसंद है जहां कोई अलग डिस्पैचर ऑब्जेक्ट नहीं हैं और एक्शन ऑब्जेक्ट स्वयं डिस्पैचिंग करते हैं।


संपादित करें: फेसबुक का फ्लक्स वास्तव में "एक्शन क्रिएटर्स" में मिलता है, इसलिए वे स्मार्ट एक्शन का उपयोग करते हैं। वे दुकानों का उपयोग कर पेलोड भी तैयार करते हैं:

https://github.com/facebook/flux/blob/19a24975462234ddc583ad740354e115c20b881d/examples/flux-chat/js/actions/Chat/essageActionCreators.js#L27 (पंक्ति 27 और 28)

पूरा होने पर कॉलबैक इस बार पेलोड के रूप में प्राप्त आंकड़ों के साथ एक नई कार्रवाई को ट्रिगर करेगा:

https://github.com/facebook/flux/blob/19a24975462234ddc583ad740354e115c20b881d/examples/flux-chat/js/utils/ChatWebAPIUtils.js#L51

इसलिए मुझे लगता है कि यह बेहतर उपाय है।


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

रेफ़्लक्स फेसबुक के फ़्लक्स की थोड़ी भिन्नता है: github.com/spoike/refluxjs स्टोर्स आपके एप्लिकेशन के संपूर्ण "मॉडल" डोमेन, बनाम क्रिया / डिस्पैचर का प्रबंधन करते हैं जो केवल चीजों को एक साथ सिलाई और गोंद करते हैं।
Rygu

1
इसलिए मैं इसके बारे में कुछ और सोच रहा हूं और (लगभग) मेरे ही सवाल का जवाब दिया है। मैंने इसे एक उत्तर के रूप में यहां जोड़ा होगा (दूसरों को वोट देने के लिए) लेकिन जाहिर तौर पर मैं स्टैकओवरफ्लो में बहुत गरीब हूं, फिर भी इसका जवाब देने में सक्षम हूं। तो यहाँ एक लिंक है: groups.google.com/d/msg/reactjs/PpsvVPvhBbc/BZoG-bFeOwoJ
plaxdan

Google समूह लिंक के लिए धन्यवाद, यह वास्तव में जानकारीपूर्ण लगता है। मैं डिस्पैचर से गुजरने वाली हर चीज का अधिक प्रशंसक हूं, और स्टोर में वास्तव में सरल तर्क है, मूल रूप से, अपने डेटा को अपडेट करना। @Rygu मैं भाटा की जाँच करूँगा।
जेरेमी डी

मैंने अपना उत्तर एक वैकल्पिक दृश्य के साथ संपादित किया। लगता है दोनों समाधान संभव हैं। मैं लगभग निश्चित रूप से दूसरों पर फेसबुक का समाधान चुनूंगा।
रयगु सिप

3

मैं "गूंगा" क्रियाओं के पक्ष में एक तर्क प्रदान करूँगा।

अपने कार्यों में दृश्य डेटा एकत्र करने की ज़िम्मेदारी निभाते हुए, आप अपने विचारों की डेटा आवश्यकताओं के लिए अपने कार्यों को जोड़े।

इसके विपरीत, जेनेरिक क्रियाएं, जो उपयोगकर्ता के इरादे का वर्णन करती हैं , या आपके आवेदन में कुछ राज्य संक्रमण करती हैं, किसी भी स्टोर को उस कार्रवाई का जवाब देती है, जो इरादे को बदलने के लिए विशेष रूप से सिलसिलेवार रूप से अनुकूलित राज्य में कार्रवाई करती है।

यह खुद को और अधिक, लेकिन छोटे, अधिक विशिष्ट स्टोरों के लिए उधार देता है। मैं इस शैली के लिए तर्क देता हूं क्योंकि

  • यह आपको स्टोर डेटा को देखने के तरीकों में अधिक लचीलापन देता है
  • "स्मार्ट" स्टोर, उनके उपभोग करने वाले विचारों के लिए विशेष, "स्मार्ट" क्रियाओं की तुलना में जटिल ऐप्स के लिए छोटे और कम युग्मित होंगे, जिस पर संभावित रूप से कई विचार निर्भर करते हैं

एक स्टोर का उद्देश्य विचारों को डेटा प्रदान करना है। "एक्शन" नाम मुझे बताता है कि इसका उद्देश्य मेरे एप्लिकेशन में परिवर्तन का वर्णन करना है।

मान लीजिए कि आपको एक मौजूदा डैशबोर्ड दृश्य में एक विजेट जोड़ना है, जो कुछ फैंसी नए एग्रीगेट डेटा को दिखाता है जो आपकी बैकएंड टीम अभी-अभी लुढ़की है।

"स्मार्ट" क्रियाओं के साथ, आपको नए एपीआई का उपभोग करने के लिए अपने "रिफ्रेश-डैशबोर्ड" एक्शन को बदलने की आवश्यकता हो सकती है। हालांकि, "डैशबोर्ड को ताज़ा करना" एक अमूर्त अर्थ में नहीं बदला है। आपके विचारों की डेटा आवश्यकताएं बदल गई हैं।

"गूंगा" क्रियाओं के साथ, आप उपभोग करने के लिए नए विजेट के लिए एक नया स्टोर जोड़ सकते हैं, और इसे सेट कर सकते हैं ताकि जब इसे "रिफ्रेश-डैशबोर्ड" एक्शन टाइप मिले, तो यह नए डेटा के लिए एक अनुरोध भेजता है, और इसे उजागर करता है तैयार होने के बाद नया विजेट। यह मेरे लिए समझ में आता है कि जब दृश्य परत को अधिक या अलग डेटा की आवश्यकता होती है, तो जो चीजें मैं बदलता हूं, वे उस डेटा के स्रोत हैं: स्टोर।


2

गैरों के फ्लक्स-रिएक्शन-राउटर-डेमो में 'सही' दृष्टिकोण की एक अच्छी उपयोगिता भिन्नता है।

एक ActionCreator एक बाहरी API सेवा से एक वादा करता है, और फिर dispatchAsyncएक प्रॉक्सी / विस्तारित डिस्पैचर में एक फ़ंक्शन के लिए वादा और तीन कार्रवाई स्थिरांक पास करता है। dispatchAsyncहमेशा पहली कार्रवाई जैसे 'GET_EXTERNAL_DATA' और एक बार वादे के बाद इसे 'GET_EXTERNAL_DATA_SUCCESS' या 'GET_EXTERNAL_DATA_ERROR' भेज देगा।


1

यदि आप चाहते हैं कि एक दिन आपके पास ब्रेट विक्टर के प्रसिद्ध वीडियो इन्वेंटिंग ऑन प्रिंसिपल में देखे जाने के लिए एक विकास का माहौल हो , तो आपको बिना किसी साइड इफ़ेक्ट के केवल डेटा संरचना के अंदर क्रियाओं / घटनाओं का प्रक्षेपण करना चाहिए। यह भी मदद करेगा अगर आपके स्टोर वास्तव में उसी वैश्विक अपरिवर्तनीय डेटा संरचना के सदस्य थे, जैसे Redux में

अधिक स्पष्टीकरण यहाँ: https://stackoverflow.com/a/31388262/82609

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