𝗹𝗼𝗱𝗮𝘀𝗵.𝗺𝗲𝗺𝗼𝗶𝘇𝗲 से सावधान रहें
Lodash memoize मुफ्त परफॉरमेंस जैसा लगता है। आप एक फंक्शन को रैप करते हैं और आपको एक कैश (cache) मिल जाता है।
लेकिन इसके डिफ़ॉल्ट व्यवहार में एक जाल (trap) है। यह केवल पहले आर्गुमेंट (argument) से कैश की (cache key) बनाता है। यह बाकी सभी आर्गुमेंट्स को नज़रअंदाज़ कर देता है।
अगर आप एक आर्गुमेंट का उपयोग करते हैं, तो आप सुरक्षित हैं। अगर आप दो या अधिक का उपयोग करते हैं, तो आप बग्स (bugs) पैदा कर देते हैं।
इस उदाहरण को देखें:
const add = memoize((a, b) => a + b);
add(1, 2); // 3 लौटाता है। यह की (key) 1 के तहत परिणाम को कैश करता है।
add(1, 9); // 3 लौटाता है। यह गलत है। इसे 10 होना चाहिए था।
Lodash फिर से 1 देखता है। उसे कैश में 1 मिल जाता है। यह पुराना परिणाम लौटा देता है। यह 9 को कभी देखता ही नहीं है।
करेंसी फॉर्मेटिंग (Currency formatting) एक आम जाल है।
const formatPrice = memoize((amount, currency) =>
new Intl.NumberFormat('en', { style: 'currency', currency }).format(amount)
);
formatPrice(100, 'USD'); // "$100.00" लौटाता है। की (key) 100 है।
formatPrice(100, 'EUR'); // "$100.00" लौटाता है। यह गलत है।
दूसरी कॉल 'EUR' को नज़रअंदाज़ कर देती है। यह कैश में 100 देखती है और यूरो के बजाय डॉलर लौटा देती है। इसमें कोई एरर (error) नहीं आता। कोई चेतावनी (warning) नहीं मिलती। आप बस अपने उपयोगकर्ताओं को गलत पैसे दिखाते हैं।
कैश की (cache key) को परिभाषित करने के लिए आपको दूसरा आर्गुमेंट देना होगा। इस की (key) में हर इनपुट शामिल होना चाहिए।
const formatPrice = memoize(
(amount, currency) =>
new Intl.NumberFormat('en', { style: 'currency', currency }).format(amount),
(amount, currency) => `${amount}|${currency}`
);
formatPrice(100, 'USD'); // "$100.00"
formatPrice(100, 'EUR'); // "€100.00"
की (key) में वह सब कुछ शामिल होना चाहिए जो आउटपुट को बदलता है।
एक अंतिम विचार: मेमोइज़ेशन (memoization) जोखिम बढ़ाता है। इसका उपयोग तभी करें जब कोई फंक्शन 'expensive' हो और अक्सर समान इनपुट्स के साथ चलता हो। साधारण फंक्शन्स के लिए, उन्हें बस कॉल करें। बग होने का जोखिम अक्सर उस गति से अधिक होता है जो आप प्राप्त करते हैं।
मुख्य बातें:
- डिफ़ॉल्ट कीज़ (keys) केवल पहले आर्गुमेंट का उपयोग करती हैं।
- की (key) में सभी आर्गुमेंट्स को शामिल करने के लिए एक रिज़ॉल्वर (resolver) का उपयोग करें।
- एक अच्छी की (key) वह सब कुछ दर्शाती है जो आउटपुट को बदलता है।
- सस्ते (cheap) फंक्शन्स के लिए memoize का उपयोग न करें।
स्रोत: https://dev.to/figsify/beware-of-lodashmemoize-it-only-remembers-the-first-argument-4cjl