क्लोजर वायदा और वादे अलग कैसे होते हैं?


86

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


8
मुझे यकीन नहीं है कि प्रश्न पर -1 क्यों है, या ऐसे प्रश्न हैं जहां अब आपको बुरी बातें पूछने से पहले जवाब नहीं पता है?
मेरे सही

मैंने कोई जवाब नहीं दिया -1 ?? हम यह कैसे बता सकते हैं कि किसने क्सिटॉन या उत्तर पर -1 लगाया है?
appshare.co

आप और मैं, जुबैर नहीं कर सकते। मैं सिर्फ उत्सुक हूं जिसने आपके प्रश्न पर -1 दिया है जो यह पूछने के लिए पूरी तरह से उचित प्रश्न है और यह निश्चित रूप से एसओ के लिए विषय है।
सिर्फ मेरा सही जनधन

जवाबों:


54

क्लीजुर शब्दों में उत्तर दें, यहाँ सीन देवलिन के स्क्रैन्कास्ट के कुछ उदाहरण दिए गए हैं :

(def a-promise (promise))
(deliver a-promise :fred)

(def f (future (some-sexp)))
(deref f)

ध्यान दें कि वादे में आप स्पष्ट रूप से एक मूल्य दे रहे हैं जिसे आप बाद की गणना में चुनते हैं ( :fredइस मामले में)। दूसरी ओर, भविष्य को उसी स्थान पर उपभोग किया जा रहा है जहां इसे बनाया गया था। some-exprशायद पर्दे के पीछे शुरू की है और मिलकर (अंततः) में गणना की है, लेकिन अगर यह समय से बनी हुई है unevaluated यह धागा ब्लॉक पहुँचा जा सकता है जब तक यह उपलब्ध है।


जोड़ने के लिए संपादित किया गया

एक वादे और भविष्य के बीच भेद करने में मदद करने के लिए, निम्नलिखित पर ध्यान दें:

वादा

  1. आप एक बनाएँ promise। वह वादा वस्तु अब किसी भी धागे से पारित की जा सकती है।
  2. आप गणना के साथ जारी रखें। ये साइड-इफेक्ट्स, डाउनलोडिंग डेटा, उपयोगकर्ता इनपुट, डेटाबेस एक्सेस, अन्य वादों से जुड़े बहुत जटिल गणना हो सकते हैं - जो भी आपको पसंद हो। किसी भी प्रोग्राम में कोड आपके मेनलाइन कोड की तरह ही दिखेगा।
  3. जब आप समाप्त कर लें, तो आप deliverउस वादे वाली वस्तु को परिणाम दे सकते हैं ।
  4. derefआपके द्वारा अपनी गणना के पूरा होने से पहले आपके वादे को पूरा करने की कोशिश करने वाला कोई भी आइटम तब तक ब्लॉक रहेगा जब तक आप काम नहीं कर लेते। एक बार जब आप पूरा कर लेते हैं और आपने deliverवादे को पूरा कर लिया है , तो वादा पूरा नहीं होगा।

भविष्य

  1. आप अपना भविष्य बनाएं। आपके भविष्य का हिस्सा गणना के लिए एक अभिव्यक्ति है।
  2. भविष्य समवर्ती रूप से निष्पादित या नहीं हो सकता है। यह एक धागा सौंपा जा सकता है, संभवतः एक पूल से। यह सिर्फ इंतजार कर सकता था और कुछ नहीं कर सकता था। अपने दृष्टिकोण से आप नहीं बता सकते
  3. कुछ बिंदु पर आप (या एक और धागा) derefभविष्य को देखते हैं। यदि गणना पहले ही पूरी हो गई है, तो आपको इसके परिणाम मिलते हैं। यदि यह पहले से ही पूरा नहीं हुआ है, तो आपके पास तब तक ब्लॉक रहता है, जब तक इसके पास नहीं है। (संभवतः अगर यह अभी तक शुरू नहीं हुआ है, derefतो इसका मतलब है कि यह निष्पादित करना शुरू कर देता है, लेकिन यह भी, गारंटी नहीं है।)

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


लेकिन आप या तो एक वादा या भविष्य समाप्त होने तक कोई भी कैलीकुलेशन ब्लॉक कर सकते हैं। अर्थात: (@a + @b) भविष्य और वचन दोनों के साथ समान काम करेगा
appshare.co

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

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

2
सिर्फ रिकॉर्ड के लिए, एक futureकॉल के शरीर में एन सेक्सप्रॉसेस शामिल हो सकते हैं।
vemv

यह स्पष्टीकरण क्लोजर डॉक्टर
पीयूष कटारिया

25

भविष्य और वादा दोनों निर्माता से उपभोक्ता (उपभोक्ता) के लिए अतुल्यकालिक गणना के परिणाम संवाद करने के लिए तंत्र हैं । भविष्य के

मामले में गणना भविष्य के निर्माण के समय पर परिभाषित की जाती है और एसिंक्स निष्पादन "एएसएपी" शुरू होता है। यह भी "जानता है" कि कैसे एक अतुल्यकालिक गणना स्पॉन करें। अभिकलन की प्रतिज्ञा के मामले में , इसके प्रारंभ समय और [संभव] अतुल्यकालिक आह्वान को वितरण तंत्र से अलग कर दिया जाता है। जब अभिकलन परिणाम उपलब्ध होता है तो निर्माता को स्पष्ट रूप से कॉल करना चाहिए , जिसका अर्थ यह भी है कि परिणाम उपलब्ध होने पर निर्माता नियंत्रण करता है।

deliver

प्रॉमिस क्लोजर के लिए एक ही वस्तु ( promiseकॉल का परिणाम ) का उपयोग करके दोनों उत्पादन ( deliver) और उपभोग ( deref) की गणना के परिणामस्वरूप एक डिजाइन गलती करता है । ये दो बहुत अलग क्षमताएं हैं और इन्हें इस तरह से माना जाना चाहिए।


@oskarkv मान लीजिए आपने एक वादा किया है और इसे 3 ग्राहकों को दिया है। कुछ भी नहीं एक ग्राहक को फर्जी परिणाम के साथ इसे हल करने और दो अन्य ग्राहकों को संकेत देने से रोकता है। साथ ही आप इस वादे को अब नहीं सुलझा पाएंगे। इसके विपरीत, यदि आपके पास एक वादा + रिज़ॉल्वर जोड़ी है, तो अपने ग्राहकों को वादा दिया और अपने लिए रिज़ॉल्वर रखा, यह परिदृश्य असंभव हो जाता है। अधिक जानकारी के लिए सुझाए गए खोज शब्द "क्षमता आधारित अभिगम नियंत्रण" और "क्षमता आधारित सुरक्षा" हैं।
दीमागॉग

1
मुझे यकीन नहीं है कि क्या इस तरह के एक साधारण संदर्भ प्रकार के लिए सुरक्षा युग्मित करना (इसके निहित की जांच करना) promiseसुविधाजनक है। 'ईविल' उपभोक्ता दुर्लभ हैं; कुछ भी आपको वादों के शीर्ष पर अपने स्वयं के अमूर्त निर्माण से नहीं रोकता है।
vemv

8
यह सुरक्षा के बारे में नहीं है, यह सिर्फ इतना है कि क्षमता-आधारित प्रोग्रामिंग अक्सर सुरक्षा के संबंध में वर्णित है। यहाँ यह कोड शुद्धता के बारे में है। अक्सर उपयोग किया जाने वाला शब्द "निर्माण द्वारा सही" है और सवाल यह है कि "क्या आप एक गलत कार्यक्रम का निर्माण कर सकते हैं"? उद्देश्य पर नहीं, बल्कि दुर्घटना से। सिंगल प्रॉमिस ऑब्जेक्ट के साथ, जबकि आप दो अलग-अलग ऑब्जेक्ट के साथ नहीं कर सकते।
दिमागॉग

कुछ भी नहीं है जो आपको एक वादा वापस करने से रोक रहा है, हालांकि, यदि आप चाहते हैं कि इसे वितरित नहीं किया जा सकता है: (defn undeliverable-promise [] (let [p (promise)] (reify clojure.lang.IDeref (deref [_] (deref p)) clojure.lang.IBlockingDeref (deref [_ ms val] (deref p ms val)) clojure.lang.IPending (isRealized [_] (.isRealized p)) clojure.lang.IFn (invoke [_ _] nil))))
टेपिचू

इस अंतर की ओर इशारा करते हुए कि कैसे गणना तंत्र को डिकूप किया जाता है, इस पद को वास्तव में संक्षिप्त व्याख्या करता है। धन्यवाद!
सिंथोमैट

3

पहले से ही उत्कृष्ट उत्तर हैं इसलिए केवल "कैसे उपयोग करें" सारांश को जोड़ना:

दोनों

वादा या भविष्य बनाना तुरंत एक संदर्भ देता है। यह संदर्भ @ / deref पर ब्लॉक करता है जब तक कि गणना का परिणाम अन्य धागे द्वारा प्रदान नहीं किया जाता है।

भविष्य

भविष्य बनाते समय आप एक समकालिक नौकरी प्रदान करते हैं। यह समर्पित अनबाउंड पूल से एक थ्रेड में निष्पादित होता है।

वादा

वादा करते समय आप कोई तर्क नहीं देते। संदर्भ को अन्य 'उपयोगकर्ता' थ्रेड में भेजा जाना चाहिए deliverजो परिणाम देगा।


1

क्लोजर में promise,, futureऔर, delayवादे जैसी वस्तुएं हैं। वे सभी एक अभिकलन का प्रतिनिधित्व करते हैं जिसका उपयोग करके ग्राहक प्रतीक्षा कर सकते हैं deref(या @)। ग्राहक परिणाम का पुन: उपयोग करते हैं, ताकि गणना कई बार न चले।

वे गणना के प्रदर्शन के तरीके में भिन्न होते हैं:

  • futureएक अलग कार्यकर्ता सूत्र में गणना शुरू करेगा। derefपरिणाम तैयार होने तक ब्लॉक रहेगा।

  • delayजब पहले ग्राहक उपयोग करता है deref, या , अभिकलन आलस्य का प्रदर्शन करेगा force

  • promiseसबसे अधिक लचीलापन प्रदान करता है, क्योंकि इसका परिणाम किसी भी कस्टम तरीके से उपयोग करके दिया जाता है deliver। आप इसे जब न का उपयोग futureया delayआपके उपयोग के मामले से मेल खाते हैं।


-4

सबसे पहले, एक Promiseएक है Future। मुझे लगता है कि आप ए Promiseऔर ए के बीच अंतर जानना चाहते हैं FutureTask

एक Futureऐसे मूल्य का प्रतिनिधित्व करता है जो वर्तमान में ज्ञात नहीं है लेकिन भविष्य में जाना जाएगा।

A FutureTaskभविष्य में होने वाली गणना (शायद किसी थ्रेड पूल में) के परिणाम का प्रतिनिधित्व करता है। जब आप परिणाम तक पहुंचने का प्रयास करते हैं, यदि गणना अभी तक नहीं हुई है, तो यह ब्लॉक हो जाती है। अन्यथा परिणाम तुरंत वापस आ जाता है। परिणाम की गणना में कोई अन्य पार्टी शामिल नहीं है क्योंकि गणना आपके द्वारा पहले से निर्दिष्ट है।

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

उस अर्थ में, FutureTaskएक Promiseआप अपने आप को बनाया है।


क्या आप सुनिश्चित हैं कि एक वादा एक भविष्य है? मुझे नहीं लगता कि यह इंटरफ़ेस लागू करता है। github.com/richhickey/clojure/blob/…
Mikael Sundberg

क्षमा करें, मैं गलत तरीके से दर्ज किया गया। मेरा सवाल बदल गया है
मिकेल सुंदरबर्ग

मेरा उत्तर सामान्य अर्थों में है, क्लोजर विशिष्ट में नहीं।
अभिनव सरकार

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