paint-brush
सब कुछ जो आपको वादों, तत्संबंधी, और आलसी-मूल्यांकन के बारे में जानने की आवश्यकता हैद्वारा@austingil
1,647 रीडिंग
1,647 रीडिंग

सब कुछ जो आपको वादों, तत्संबंधी, और आलसी-मूल्यांकन के बारे में जानने की आवश्यकता है

द्वारा Austin Gil5m2023/01/20
Read on Terminal Reader

बहुत लंबा; पढ़ने के लिए

नए साल में, मैं आपको दिखाने जा रहा हूं कि 'वादे' को और आलसी कैसे बनाया जाए। आइए बुनियादी `वादे’ का उदाहरण देखें। यहां, मेरे पास नींद नामक एक फ़ंक्शन है जो मिलीसेकंड और एक मान में समय लेता है। यह एक वादा लौटाता है जो मिलीसेकंड की संख्या के लिए `सेटटाइमआउट` निष्पादित करेगा जिसका हमें इंतजार करना चाहिए।
featured image - सब कुछ जो आपको वादों, तत्संबंधी, और आलसी-मूल्यांकन के बारे में जानने की आवश्यकता है
Austin Gil HackerNoon profile picture

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


यह एक पल में और अधिक समझ में आएगा।

सबसे पहले, आइए बुनियादी Promise उदाहरण देखें। यहां, मेरे पास नींद नामक एक फ़ंक्शन है जो मिलीसेकंड और एक मान में समय लेता है। यह एक वादा देता है जो मिलीसेकंड की संख्या के लिए एक setTimeout निष्पादित करेगा जिसे हमें इंतजार करना चाहिए; तब वादा मूल्य के साथ हल हो जाता है।


 /** * @template ValueType * @param {number} ms * @param {ValueType} value * @returns {Promise<ValueType>} */ function sleep(ms, value) { return new Promise((resolve) => { setTimeout(() => resolve(value), ms); }); }


यह इस तरह काम करता है:


कोड के साथ जावास्क्रिप्ट कंसोल, "नींद का इंतजार करें (1000, 'जम्हाई और खिंचाव')"। फिर एक सेकंड के बाद, "'यॉन एंड स्ट्रेच'"


हम 1000 और 'Yawn & stretch' के तर्कों के साथ sleep फंक्शन का इंतजार कर सकते हैं, और एक सेकंड के बाद, console 'यॉन एंड स्ट्रेच' स्ट्रिंग को लॉग करेगा।


इसमें कुछ भी खास नहीं है। यह शायद वैसा ही व्यवहार करता है जैसा आप उम्मीद करेंगे, लेकिन यह थोड़ा अजीब हो जाता है अगर हम इसे बाद में await करने के लिए एक चर के रूप में संग्रहीत करते हैं, बजाय इसके कि तुरंत लौटाए गए Promise का await करें।


 const nap = sleep(1000, 'Yawn & stretch')


अब, मान लें कि हम कोई अन्य कार्य करते हैं जिसमें समय लगता है (जैसे अगला उदाहरण टाइप करना), और फिर nap चर await करें।


जावास्क्रिप्ट कंसोल में टाइप करना, "झपकी का इंतजार करना" और तुरंत प्रतिक्रिया "'जम्हाई और खिंचाव'" देखना

हल करने से पहले आप एक सेकंड की देरी की उम्मीद कर सकते हैं, लेकिन वास्तव में, यह तुरंत हल हो जाता है। जब भी आप एक Promise बनाते हैं, तो आप इसके लिए जिम्मेदार किसी भी अतुल्यकालिक कार्यक्षमता को तुरंत चालू कर देते हैं।


हमारे उदाहरण में, जिस क्षण हम nap वेरिएबल को परिभाषित करते हैं, Promise बन जाता है जो setTimeout को निष्पादित करता है। क्योंकि मैं धीमा टाइपर हूं, जब तक हम इसका await करेंगे, तब तक Promise हल हो जाएगा।


दूसरे शब्दों में, Promise एस उत्सुक हैं। वे आपकी प्रतीक्षा करने के लिए आपकी await नहीं करते हैं।


कुछ मामलों में, यह अच्छी बात है। अन्य मामलों में, यह अनावश्यक संसाधन उपयोग को जन्म दे सकता है। उन परिदृश्यों के लिए, आप ऐसा कुछ चाहते हैं जो Promise जैसा दिखता हो, लेकिन उपयोग करता हो आलसी मूल्यांकन जरूरत पड़ने पर केवल तत्काल करने के लिए।


इससे पहले कि हम आगे बढ़ें, मैं आपको कुछ दिलचस्प दिखाना चाहता हूँ।


Promise केवल ऐसी चीजें नहीं हैं जिन्हें जावास्क्रिप्ट में await किया जा सकता है। यदि हम एक .then() विधि के साथ एक सादा Object बनाते हैं, तो हम वास्तव में किसी भी Promise की तरह ही उस वस्तु await कर सकते हैं।


टेक्स्ट के साथ JavaScript कंसोल, "प्रतीक्षा करें { फिर: () => कंसोल.लॉग('🙃') }" और उसके बाद "🙃"।

यह एक तरह से अजीब है, लेकिन यह हमें अलग-अलग ऑब्जेक्ट बनाने की भी अनुमति देता है जो Promise की तरह दिखते हैं, लेकिन हैं नहीं। इन वस्तुओं को कभी-कभी "कहा जाता है" फिर योग्य "।


इसे ध्यान में रखते हुए, आइए एक नया बनाएं कक्षा LazyPromise कहा जाता है जो बिल्ट-इन Promise कंस्ट्रक्टर का विस्तार करता है। विस्तार वादा सख्ती से जरूरी नहीं है, लेकिन यह instanceof जैसी चीजों का उपयोग करके इसे Promise के समान दिखाई देता है।


 class LazyPromise extends Promise { /** @param {ConstructorParameters<PromiseConstructor>[0]} executor */ constructor(executor) { super(executor); if (typeof executor !== 'function') { throw new TypeError(`LazyPromise executor is not a function`); } this._executor = executor; } then() { this.promise = this.promise || new Promise(this._executor); return this.promise.then.apply(this.promise, arguments); } }


ध्यान केंद्रित करने वाला हिस्सा then() विधि है। यह वास्तविक Promise बनाने से पहले .then() विधि निष्पादित होने तक प्रतीक्षा करने के लिए मानक Promise के डिफ़ॉल्ट व्यवहार को हाइजैक करता है।


जब तक आप वास्तव में इसके लिए कॉल नहीं करते हैं, तब तक एसिंक्रोनस कार्यक्षमता को तुरंत चालू करने से बचा जाता है। और यह काम करता है कि क्या आप स्पष्ट रूप से .then() को कॉल करते हैं या await का उपयोग करते हैं।


अब देखते हैं कि क्या होता है यदि हम मूल sleep फंक्शन में LazyPromise के साथ Promise को बदल दें। एक बार फिर, हम परिणाम को एक nap वेरिएबल को असाइन करेंगे।


 function sleep(ms, value) { return new LazyPromise((resolve) => { setTimeout(() => resolve(value), ms); }); } const nap = sleep(1000, 'Yawn & stretch')


फिर हम अपना समय await nap लाइन को टाइप करने और उसे निष्पादित करने में लगाते हैं।


जावास्क्रिप्ट कंसोल में टाइप करना, "झपकी का इंतजार करना" और एक सेकंड की देरी के बाद, प्रतिक्रिया "'जम्हाई और खिंचाव'" देखना


इस बार, हम Promise पूरा होने से पहले एक सेकंड की देरी देखते हैं, भले ही वेरिएबल बनाए जाने के बाद कितना समय बीत चुका हो।


(ध्यान दें कि यह कार्यान्वयन केवल एक बार नया Promise बनाता है और इसे बाद की कॉल में संदर्भित करता है। इसलिए यदि हम इसे फिर से await करते हैं, तो यह किसी भी सामान्य Promise की तरह तुरंत हल हो जाएगा)


बेशक, यह एक मामूली उदाहरण है कि आप शायद उत्पादन कोड में नहीं पाएंगे, लेकिन ऐसी कई परियोजनाएं हैं जो आलसी-मूल्यांकन किए गए Promise -जैसी वस्तुओं का उपयोग करती हैं। संभवतः सबसे आम उदाहरण डेटाबेस ORM s और क्वेरी बिल्डर्स जैसे हैं क्नेक्स.जेएस या प्रिस्मा .


नीचे छद्म कोड पर विचार करें। यह इनमें से कुछ क्वेरी बिल्डरों से प्रेरित है:


 const query = db('user') .select('name') .limit(10) const users = await query


हम एक डेटाबेस क्वेरी बनाते हैं जो "user" तालिका में जाती है और पहली दस प्रविष्टियों का चयन करती है और उनके नाम लौटाती है। सिद्धांत रूप में, यह एक नियमित Promise के साथ ठीक काम करेगा।


लेकिन क्या होगा अगर हम क्वेरी स्ट्रिंग पैरामीटर जैसी कुछ शर्तों के आधार पर क्वेरी को संशोधित करना चाहते हैं? Promise का इंतजार करने से पहले क्वेरी को संशोधित करना जारी रखना अच्छा होगा।


 const query = db('user') .select('name') .limit(10) if (orderBy) { query.orderBy(orderBy) } if (limit) { query.limit(limit) } if (id) { query.where({ id: id }) } const users = await query


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


आलसी मूल्यांकन के साथ, हम इस तरह का कोड लिख सकते हैं जिसका पालन करना आसान है, डेवलपर अनुभव में सुधार करता है, और केवल एक बार क्वेरी को निष्पादित करता है जब हमें इसकी आवश्यकता होती है।


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


लेज़ी Promise सही उपयोग के मामलों के लिए बहुत अच्छे हैं, लेकिन यह कहना नहीं है कि उन्हें हर Promise को बदलना चाहिए। कुछ मामलों में, उत्सुकता से तत्काल करना और जितनी जल्दी हो सके प्रतिक्रिया तैयार करना फायदेमंद होता है।


यह उन "यह निर्भर करता है" परिदृश्यों में से एक है। लेकिन अगली बार जब कोई आपसे कोई Promise करने के लिए कहे, तो इसके बारे में आलसी होने पर विचार करें।


पढ़ने के लिए आपको बहुत बहुत शुक्रिया। अगर आपको यह लेख पसंद आया हो तो प्लीज इसे शेयर करें . यह मेरा समर्थन करने के सर्वोत्तम तरीकों में से एक है। आप भी कर सकते हैं मेरे न्यूज़लैटर के लिए साइन अप करें या मुझे ट्वीटर पर अनुगमन कीजीए यदि आप जानना चाहते हैं कि नए लेख कब प्रकाशित होते हैं।


मूल रूप से पर प्रकाशित किया गया austingil.com .