2013-01-09 20 views
18

हाल ही में कुछ सहकर्मियों और मैं चर्चा कर रहा था कि AngularJS सेवाओं के पास राज्य होना चाहिए या नहीं। हम इसके लिए और इसके खिलाफ कुछ तर्क लेकर आए और मैं इस विषय पर अतिरिक्त विचार और प्रतिक्रिया प्राप्त करना चाहता था। मेरी खोज में मुझे this मिला लेकिन उल्लेख किया गया कोई स्पष्ट सर्वोत्तम अभ्यास प्रतीत नहीं होता है। किसी भी ग्राहक-पक्ष की दुनिया में किसी सेवा को कभी भी राज्य नहीं रखना चाहिए, लेकिन मुझे लगता है कि यह स्वीकार्य क्लाइंट-साइड हो सकता है क्योंकि यह एक अलग समस्या है। राज्य पकड़े सेवाओं के लिएक्या एक कोणीय सेवा राज्य होना चाहिए?

कारण:

  1. सेवा एक से अधिक थ्रेड द्वारा पहुँचा जा करने के लिए नहीं जा रहा है। प्रत्येक ब्राउज़र के पास सेवा का अपना उदाहरण होगा।
  2. सेवा को केवल राज्य को पकड़ने की अनुमति देता है, केवल रूटस्कोप में इसे संग्रहीत करने की बजाय इसकी परवाह करता है।

    1. सेवाएं idempotent अब कर रहे हैं: राज्य पकड़ नहीं करने के लिए सेवाओं के लिए

    कारण समाहित। कॉलिंग फ़ंक्शंस राज्य बदल सकता है और इसलिए सेवा की स्थिति के आधार पर इसे कॉल करते समय अलग-अलग परिणाम हो सकते हैं।

  3. मुझे लगता है कि कुल मिलाकर परीक्षण करना आसान होगा।

एक तरीका जो "राज्य होल्डिंग स्टेटस" अनुभाग में # 2 को संबोधित कर सकता है, उस रूटस्टॉप पर एक ऐपस्टेट ऑब्जेक्ट सेट होना होगा जिसमें एप्लिकेशन की वर्तमान स्थिति हो। तब सभी राज्य एक स्थान पर इकट्ठे किए जाएंगे और फिर आप अपनी सेवा में जो कुछ भी चाहते हैं उसे खींच लेंगे। मैंने यह पाया और

उत्तर

9

AngularJS में, सेवाएं are passed in via factory function। और मूल रूप से वे ऑब्जेक्ट्स होते हैं जिनमें कुछ राज्य हो सकता है (उदा। उनके कार्यों को करने के लिए आवश्यक डेटा को कैशिंग या संग्रहीत करने के लिए)।

एक अच्छा समाधान जो राज्य होने/रखने का दोनों विपक्ष ले सकता है, वह सेवा है (जो वास्तव में कार्य कर सकती है) जो उस स्थिति को वापस लौटाती है जिसमें राज्य होता है।

$http सेवा पर एक नज़र डालें: यदि आप इस सेवा

var x = $http({url:'...'}); 

बुलाने की उदाहरण प्राप्त कर सकते हैं और फिर

var result = x.get() //actually `$http.get` is shortcut of this operation 

ngResource के साथ भी यही से बुलाते: सेवा का उपयोग कर आप कुछ राज्य के साथ वस्तु मिल जो वांछित कार्यों को कर सकते हैं।

तो मूल रूप से मुझे लगता है कि यह सबसे अच्छा विकल्प है: एक बिंदु से आप राज्य को स्थानांतरित करके 'साइड इफेक्ट्स' से बचें जिन्हें अलग-अलग ऑब्जेक्ट में क्रियाओं द्वारा संशोधित किया जा सकता है, सेवा में ही संग्रहीत नहीं किया जाता है, लेकिन उस ऑब्जेक्ट में विशिष्ट स्थिति हो सकती है कस्टम जानकारी स्टोर करने में सक्षम होने के लिए (जैसे ऑथ सूचना आदि)।

+0

$ http और $ संसाधन के बारे में अच्छे अंक। साथ ही, मुझे केवल राज्य को संग्रहीत करने के बारे में आपका विचार पसंद है जो सेवा पर बुलाए गए कार्यों द्वारा संशोधित नहीं किया जाएगा (सेवा को प्रारंभ करते समय शायद छोड़कर)। – testing123

13

यह संभवतः "राज्य" से आपका क्या मतलब है, इस पर निर्भर करेगा, लेकिन कई मामलों में मुझे लगता है कि उत्तर हाँ होगा: सेवाएं होल्ड राज्य होना चाहिए।

उदाहरण के लिए, यदि आपके पास ऐसी सेवा है जो किसी एपीआई के साथ संचार के लिए ज़िम्मेदार है, तो वह सेवा प्रमाणीकरण स्थिति रख सकती है।

वैसे, मुझे यकीन नहीं है कि एंगुलरजेएस सेवाओं के लिए कितना बेवकूफता है - वे अकेले हैं और इसलिए स्वाभाविक रूप से कुछ राज्य हैं। आप (और कुछ मामलों में) सेवा पर बेवकूफ तरीकों को बना सकते हैं, लेकिन यह एक अलग मुद्दा है।

+0

प्रमाणीकरण स्थिति रखने के बारे में अच्छा बिंदु। सेवा बेवकूफ बनाने के लिए, मेरा मतलब था, जैसा कि आपने उल्लेख किया है, बेवकूफ तरीके हैं। आपके उत्तर के लिए धन्यवाद। – testing123

+0

इसे राज्य में रखने के बारे में सबसे अच्छी बात यह है कि आप संदर्भ चर का उपयोग कर सकते हैं। और इसके कारण आप एक जटिल डेटा संरचना का स्पष्ट विवरण बना सकते हैं! – Exitos

1

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

-4

कारण यह नहीं है कि सेवाओं के पास राज्य नहीं होना चाहिए यह है कि जब आप सेवा तक पहुंचने वाले एकाधिक धागे होते हैं तो यह दौड़ की स्थिति की ओर जाता है।

एक सेवा में राज्य के साथ एक आम समस्या है:

  1. धागा 1 राज्य
  2. धागा 2 राज्य के लिए लिखते हैं करने के लिए लिखते हैं
  3. धागा 1 राज्य
  4. धागा 2 पढ़ता से पढ़ता राज्य से

थ्रेड 1 में अब गलत मान है।

कहा जा रहा है कि जावास्क्रिप्ट वर्तमान में सिंगल थ्रेडेड है इसलिए आपको इस तरह की थ्रेड एक्सेस समस्याएं नहीं मिलेंगी। हालांकि, मुझे चिंता होगी अगर मेरे पास ऐसी सेवा थी जहां एकाधिक असीमित $ http कॉल सभी एक ही सेवा चर पर लिख रहे थे। अगर मैं केवल रात में बेहतर सो सकता था, तो मैं अपनी सभी सेवा विधियों को लिखने की कोशिश करता था ताकि वे वास्तविक डेटा के लिए पास-थ्रू हों।

इसके बजाय, सेवा में राज्य को बनाए रखने के लिए, आप राज्य को जितना संभव हो सके बैकएंड में डाल सकते हैं। "प्रमाणीकृत" या यहां तक ​​कि चौड़ाई और ऊंचाइयों जैसी चीजें बनाए रखी जा सकती हैं और पूछताछ की जा सकती हैं। यह उपयोगकर्ताओं को ऐप से दूर नेविगेट करने की अनुमति देने के लिए कुछ संभावनाएं खोल सकता है, वापस आ सकता है और अपनी सभी प्राथमिकताओं को अभी भी सेटअप और लॉग इन कर सकता है। आप कुकी में सत्र आईडी स्टोर कर सकते हैं और बैकएंड पर यह सब सामान सहेज सकते हैं।

यदि आप राज्य को स्टोर करने के लिए एक अलग ऑब्जेक्ट रखने का मार्ग चलाते हैं, तो आप राज्य में कुछ बदलते समय सेवा से इसे निकालने में सक्षम हो सकते हैं: how to emit events from a factory। यह एक एकीकृत अनुप्रयोग स्थिति को संशोधित करने में सक्षम होने के कई सेवाएं होने का अच्छा दुष्प्रभाव होगा क्योंकि राज्य किसी भी सेवा में संग्रहीत नहीं किया जा रहा है (या कई सेवाओं के बीच खराब हो सकता है)।

+2

आपने इसे स्वयं कहा है, जावास्क्रिप्ट एकल-थ्रेडेड है, इसलिए वेबवर्कर्स के माध्यम से भी कोई दौड़ की स्थिति नहीं है, क्योंकि वेबवर्कर्स ऑब्जेक्ट्स के संदर्भ साझा कर सकते हैं। आप बैकएंड के बारे में बात कर रहे हैं, लेकिन प्रस्तुति परतों में कहा गया है कि ऐसा करने के लिए कुछ भी नहीं है दृढ़ता के साथ। – mpm