वायदा और वादा दोनों तब तक अवरुद्ध होते हैं जब तक उन्होंने अपने मूल्यों की गणना नहीं की है, इसलिए उनके बीच क्या अंतर है?
वायदा और वादा दोनों तब तक अवरुद्ध होते हैं जब तक उन्होंने अपने मूल्यों की गणना नहीं की है, इसलिए उनके बीच क्या अंतर है?
जवाबों:
क्लीजुर शब्दों में उत्तर दें, यहाँ सीन देवलिन के स्क्रैन्कास्ट के कुछ उदाहरण दिए गए हैं :
(def a-promise (promise))
(deliver a-promise :fred)
(def f (future (some-sexp)))
(deref f)
ध्यान दें कि वादे में आप स्पष्ट रूप से एक मूल्य दे रहे हैं जिसे आप बाद की गणना में चुनते हैं ( :fred
इस मामले में)। दूसरी ओर, भविष्य को उसी स्थान पर उपभोग किया जा रहा है जहां इसे बनाया गया था। some-expr
शायद पर्दे के पीछे शुरू की है और मिलकर (अंततः) में गणना की है, लेकिन अगर यह समय से बनी हुई है unevaluated यह धागा ब्लॉक पहुँचा जा सकता है जब तक यह उपलब्ध है।
जोड़ने के लिए संपादित किया गया
एक वादे और भविष्य के बीच भेद करने में मदद करने के लिए, निम्नलिखित पर ध्यान दें:
promise
। वह वादा वस्तु अब किसी भी धागे से पारित की जा सकती है।deliver
उस वादे वाली वस्तु को परिणाम दे सकते हैं ।deref
आपके द्वारा अपनी गणना के पूरा होने से पहले आपके वादे को पूरा करने की कोशिश करने वाला कोई भी आइटम तब तक ब्लॉक रहेगा जब तक आप काम नहीं कर लेते। एक बार जब आप पूरा कर लेते हैं और आपने deliver
वादे को पूरा कर लिया है , तो वादा पूरा नहीं होगा।deref
भविष्य को देखते हैं। यदि गणना पहले ही पूरी हो गई है, तो आपको इसके परिणाम मिलते हैं। यदि यह पहले से ही पूरा नहीं हुआ है, तो आपके पास तब तक ब्लॉक रहता है, जब तक इसके पास नहीं है। (संभवतः अगर यह अभी तक शुरू नहीं हुआ है, deref
तो इसका मतलब है कि यह निष्पादित करना शुरू कर देता है, लेकिन यह भी, गारंटी नहीं है।)हालांकि आप भविष्य में अभिव्यक्ति को उस कोड के रूप में जटिल बना सकते हैं जो एक वादा के निर्माण के बाद होता है, यह संदिग्ध है कि यह वांछनीय है। इसका मतलब है कि वायदा वास्तव में त्वरित, पृष्ठभूमि-सक्षम गणनाओं के लिए अधिक अनुकूल है, जबकि वादे वास्तव में बड़े, जटिल निष्पादन पथ के लिए अधिक अनुकूल हैं। बहुत, वादे उपलब्ध गणना के संदर्भ में, थोड़े अधिक लचीले और काम करने वाले वादे निर्माता की ओर उन्मुख और फसल काटने के लिए एक और धागा है। फ्यूचर्स स्वचालित रूप से एक धागा शुरू करने (बदसूरत और त्रुटि-ग्रस्त ओवरहेड के बिना) की ओर उन्मुख होते हैं और अन्य चीजों के साथ चल रहे हैं जब तक कि आप - मूल धागा - परिणामों की आवश्यकता नहीं होती है।
future
कॉल के शरीर में एन सेक्सप्रॉसेस शामिल हो सकते हैं।
भविष्य और वादा दोनों निर्माता से उपभोक्ता (उपभोक्ता) के लिए अतुल्यकालिक गणना के परिणाम संवाद करने के लिए तंत्र हैं । भविष्य के
मामले में गणना भविष्य के निर्माण के समय पर परिभाषित की जाती है और एसिंक्स निष्पादन "एएसएपी" शुरू होता है। यह भी "जानता है" कि कैसे एक अतुल्यकालिक गणना स्पॉन करें। अभिकलन
की प्रतिज्ञा के मामले में , इसके प्रारंभ समय और [संभव] अतुल्यकालिक आह्वान को वितरण तंत्र से अलग कर दिया जाता है। जब अभिकलन परिणाम उपलब्ध होता है तो निर्माता को स्पष्ट रूप से कॉल करना चाहिए , जिसका अर्थ यह भी है कि परिणाम उपलब्ध होने पर निर्माता नियंत्रण करता है। deliver
प्रॉमिस क्लोजर के
लिए एक ही वस्तु ( promise
कॉल का परिणाम ) का उपयोग करके दोनों उत्पादन ( deliver
) और उपभोग ( deref
) की गणना के परिणामस्वरूप एक डिजाइन गलती करता है । ये दो बहुत अलग क्षमताएं हैं और इन्हें इस तरह से माना जाना चाहिए।
promise
सुविधाजनक है। 'ईविल' उपभोक्ता दुर्लभ हैं; कुछ भी आपको वादों के शीर्ष पर अपने स्वयं के अमूर्त निर्माण से नहीं रोकता है।
(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))))
पहले से ही उत्कृष्ट उत्तर हैं इसलिए केवल "कैसे उपयोग करें" सारांश को जोड़ना:
दोनों
वादा या भविष्य बनाना तुरंत एक संदर्भ देता है। यह संदर्भ @ / deref पर ब्लॉक करता है जब तक कि गणना का परिणाम अन्य धागे द्वारा प्रदान नहीं किया जाता है।
भविष्य
भविष्य बनाते समय आप एक समकालिक नौकरी प्रदान करते हैं। यह समर्पित अनबाउंड पूल से एक थ्रेड में निष्पादित होता है।
वादा
वादा करते समय आप कोई तर्क नहीं देते। संदर्भ को अन्य 'उपयोगकर्ता' थ्रेड में भेजा जाना चाहिए deliver
जो परिणाम देगा।
क्लोजर में promise
,, future
और, delay
वादे जैसी वस्तुएं हैं। वे सभी एक अभिकलन का प्रतिनिधित्व करते हैं जिसका उपयोग करके ग्राहक प्रतीक्षा कर सकते हैं deref
(या @
)। ग्राहक परिणाम का पुन: उपयोग करते हैं, ताकि गणना कई बार न चले।
वे गणना के प्रदर्शन के तरीके में भिन्न होते हैं:
future
एक अलग कार्यकर्ता सूत्र में गणना शुरू करेगा। deref
परिणाम तैयार होने तक ब्लॉक रहेगा।
delay
जब पहले ग्राहक उपयोग करता है deref
, या , अभिकलन आलस्य का प्रदर्शन करेगा force
।
promise
सबसे अधिक लचीलापन प्रदान करता है, क्योंकि इसका परिणाम किसी भी कस्टम तरीके से उपयोग करके दिया जाता है deliver
। आप इसे जब न का उपयोग future
या delay
आपके उपयोग के मामले से मेल खाते हैं।
सबसे पहले, एक Promise
एक है Future
। मुझे लगता है कि आप ए Promise
और ए के बीच अंतर जानना चाहते हैं FutureTask
।
एक Future
ऐसे मूल्य का प्रतिनिधित्व करता है जो वर्तमान में ज्ञात नहीं है लेकिन भविष्य में जाना जाएगा।
A FutureTask
भविष्य में होने वाली गणना (शायद किसी थ्रेड पूल में) के परिणाम का प्रतिनिधित्व करता है। जब आप परिणाम तक पहुंचने का प्रयास करते हैं, यदि गणना अभी तक नहीं हुई है, तो यह ब्लॉक हो जाती है। अन्यथा परिणाम तुरंत वापस आ जाता है। परिणाम की गणना में कोई अन्य पार्टी शामिल नहीं है क्योंकि गणना आपके द्वारा पहले से निर्दिष्ट है।
एक Promise
परिणाम एक परिणाम का प्रतिनिधित्व करता है जो भविष्य में वादा करने वाले को दिया जाएगा। इस मामले में आप वादे करने वाले हैं और वादा करने वाला वह है जिसने आपको Promise
वस्तु दी है । FutureTask
यदि आप Promise
पूरा होने से पहले परिणाम का उपयोग करने का प्रयास करते हैं , तो इसके समान , यह तब तक अवरुद्ध हो जाता है जब तक कि प्रमोटर पूरा नहीं करता Promise
। एक बार Promise
पूरा होने पर, आपको हमेशा और तुरंत समान मूल्य मिलता है। इसके विपरीत FutureTask
, यहां एक और पार्टी शामिल है, जिसने एक बनाया Promise
। यह एक और पार्टी की गणना करने और पूरा करने के लिए जिम्मेदार है Promise
।
उस अर्थ में, FutureTask
एक Promise
आप अपने आप को बनाया है।