
Babel@7.0.0-beta52 रिलीज़ में @babel/plugin-proposal-pipeline-operator
plugin- @babel/plugin-proposal-pipeline-operator
लिए एक नया आवश्यक कॉन्फ़िगरेशन फ़्लैग है, जो @babel/plugin-proposal-pipeline-operator
के पिछले संस्करणों के लिए पिछड़ी संगतता को तोड़ता है। इस आलेख में, आप सीखेंगे कि pipeline
ऑपरेटर क्या है और इसे कॉन्फ़िगरेशन की आवश्यकता क्यों है।
UPD: स्मार्ट पाइपलाइनें babel@7.2.0 पर दिखाई दीं: https://babeljs.io/blog/2018/12/03/7.2.0#smart-pipeline-operator-parsing-8289-https-gith-com-babel-babel-babel-b पुल 8289
वर्तमान स्थिति
गिल्बर्ट गार्ज़ा , जिन्होंने मूल रूप से pipeline
ऑपरेटर का प्रस्ताव दिया था, एक पठनीय कार्यात्मक शैली में "आदेशित श्रृंखलाओं की आदेशित श्रृंखला" के लिए एक सरल वाक्यविन्यास प्राप्त करने के लिए निर्धारित किया था। पाइपलाइन ऑपरेटर F #, Hack, Elm, Elixir और अन्य जैसी भाषाओं में उत्पन्न होता है, और जब आप इसे जावास्क्रिप्ट में जोड़ते हैं, तो दो विवादास्पद मुद्दे उत्पन्न होते हैं:
- प्लेसहोल्डर्स का उपयोग कहां और कैसे करें?
async / await
पाइपलाइन में async / await
का async / await
कैसे करना चाहिए?
प्लेसहोल्डर
इस टिकट में केविन स्मिथ द्वारा पहला सवाल उठाया गया था, जहां उन्होंने हैक भाषा से पाइप शैली का उपयोग करने का सुझाव दिया था। हैक में, पाइपलाइन के किसी भी दाईं ओर प्लेसहोल्डर्स की आवश्यकता होती है, उदाहरण के लिए:
namespace Hack\UserDocumentation\Operators\Pipe\Examples\MapFilterCountPiped; function piped_example(array<int> $arr): int { return $arr |> \array_map($x ==> $x * $x, $$) |> \array_filter($$, $x ==> $x % 2 == 0) |> \count($$); } var_dump(piped_example(range(1, 10)));
हमने एक आधार के रूप में लिया कि प्लेसहोल्डर का उपयोग किसी भी अभिव्यक्ति में किया जा सकता है और अंतिम पाइपलाइन चरण से मूल्य शामिल है। यह दृष्टिकोण हमें अभिव्यक्ति लिखने का लचीलापन और पर्याप्त अवसर देता है।
सिक्के का दूसरा पहलू एक नए टोकन के जुड़ने के कारण भाषा की जटिलता है। अब तक, हमने एक हैश ( #
) चुना है, और हालांकि चर्चा अभी भी खुली है, किसी भी टोकन में संभवतः अन्य उपयोगों के साथ चौराहे होंगे। उदाहरण के लिए, हैश का उपयोग कक्षा के निजी क्षेत्रों द्वारा भी किया जाता है, वैसे ही जैसे किसी भी अन्य टोकन वेरिएंट का उपयोग किया जाता है ।
Async / प्रतीक्षारत
pipeline
स्टेटमेंट के पहले संस्करण में इस सिंटैक्स का await
:
x |> await f
क्या तैनात किया जा सकता है:
await f(x)
दुर्भाग्य से, उपयोगकर्ता ऐसी तैनाती की उम्मीद कर सकते हैं:
(await f)(x)
हालांकि async
को pipeline
से जोड़ने के बारे में बहुत सोच-विचार किया गया, लेकिन कमेटी के सदस्यों ने एक ऐसे pipeline
ऑपरेटर के खिलाफ बात की, जो async / await
समर्थन नहीं async / await
। हां, ऐसे कार्यों के साथ काम करने के विकल्प हैं जो स्पष्ट वाक्य रचना के बिना वादा करते हैं, लेकिन ये सभी विकल्प बहुत बोझिल हैं या सहायक कार्यों की आवश्यकता है।
सुझाए गए समाधान
चर्चाओं के परिणामस्वरूप, दो प्रस्तावों का गठन किया गया था (न्यूनतम विकल्प के अलावा): एफ # -पिपलाइन और स्मार्ट-पाइपलाइन का उपयोग करें। आइए इन सुझावों पर गौर करें।
यह प्रस्ताव केवल बुनियादी कार्यक्षमता पर लागू होता है। न्यूनतम संस्करण में, अतुल्यकालिक के लिए समर्थन हटा दिया जाता है और कोई प्लेसहोल्डर नहीं हैं। यह विकल्प कॉन्फ़िगरेशन की उपस्थिति से पहले पिछले संस्करणों के बेबल प्लगइन के व्यवहार से मेल खाता है, और रिपॉजिटरी में pipeline
ऑपरेटर के लिए वर्तमान विनिर्देश से मेल खाता है। यह अन्य प्रस्तावों के फायदे और नुकसान की पहचान करने के लिए एक मसौदा जांच के रूप में अधिक उपयोग किया जाता है, और वैकल्पिक प्रस्तावों में होने वाले मूलभूत परिवर्तनों के बिना स्वीकार किए जाने की संभावना नहीं है।
F # पाइपलाइन के लिए प्लेसहोल्डर्स की बिल्कुल भी जरूरत नहीं है। मूल संस्करण में, तीर फ़ंक्शंस प्लेसहोल्डर्स की आवश्यकता को कवर करते हैं, कम स्क्रिबलिंग की आवश्यकता होती है, और सभी के लिए परिचित ES2015 सिंटैक्स पर आधारित होते हैं।
फिलहाल (एफ # -संबंधों के विनिर्देश के अनुसार) तीर फ़ंक्शन को कोष्ठक में लपेटा जाना चाहिए:
let person = { score: 25 }; let newScore = person.score |> double |> (_ => add(7, _)) |> (_ => boundScore(0, 100, _));
सर्वेक्षण यह निर्धारित करने के लिए चल रहे हैं कि क्या यह कोष्ठक के बिना तीर के कार्यों का उपयोग करने के लिए संभव है, जो यहां वाक्यात्मक निरर्थक दिखते हैं।
अतुल्यकालिक के रूप में, await
# एफ पाइपलाइनों में एक असमान कार्य के रूप में काम करता है:
promise |> await
इसमें क्या खुलासा होता है:
await promise
और इसलिए अतुल्यकालिक कॉल की एक लंबी श्रृंखला के बीच में वेट का उपयोग किया जा सकता है:
promise |> await |> (x => doubleSay(x, ', ')) |> capitalize |> (x => x + '!') |> (x => new User.Message(x)) |> (x => stream.write(x)) |> await |> console.log;
इस तरह की विशेष await
प्रक्रिया संभावित रूप से अन्य यूनिरी ऑपरेटर्स (उदाहरण के लिए, typeof
) का उपयोग करने की संभावना को खोल सकती है, लेकिन एफ # पाइप के मूल विनिर्देश में उन्हें शामिल नहीं किया गया है।
स्मार पाइपलाइन प्लेसहोल्डर्स के विचार को उनके तार्किक निष्कर्ष पर लाती हैं, जिससे पिपलीन में आंशिक उपयोग और मनमाना अभिव्यक्ति दोनों की अनुमति मिलती है। पिछली लंबी श्रृंखला को इस तरह लिखा जा सकता है:
promise |> await # |> doubleSay(#, ', ') |> # || throw new TypeError() |> capitalize |> # + '!' |> new User.Message(#) |> await stream.write(#) |> console.log;
स्मार्ट पाइपलाइनों में प्लेसहोल्डर्स का उपयोग करने के नियम बहुत सरल हैं। यदि एकल पहचानकर्ता को पाइपलाइन चरण में पारित किया जाता है, तो कोई अतिरिक्त टोकन (प्लेसहोल्डर) की आवश्यकता नहीं होती है, इसे "शैली" कहा जाता है:
x |> a; x |> fb;
हैक के विपरीत, यूनिरी फ़ंक्शंस को प्लेसहोल्डर टोकन की आवश्यकता नहीं होती है।
अन्य अभिव्यक्तियों के लिए, एक प्लेसहोल्डर (जिसे "लेक्सिकल विषय टोकन" कहा जाता है) की आवश्यकता होती है, और "थीम शैली" - "विषय शैली" के भीतर काम करने के लिए एक पाइपलाइन माना जाता है। इस मामले में एक प्लेसहोल्डर टोकन की अनुपस्थिति एक प्रारंभिक सिंटेक्स एरर त्रुटि का कारण बनती है:
10 |> # + 1; promise |> await #;
यदि कोई ऑपरेटर, कोष्ठक (एक विधि को कॉल करने के लिए), उद्धरण चिह्नों, या एक पहचानकर्ता और एक डॉट के अलावा कुछ और हैं, तो प्लेसहोल्डर टोकन की आवश्यकता है। इससे पैर में गोली लगने से बचने और अनिश्चितता को खत्म करने में मदद मिलेगी।
स्मार्ट पाइपलाइन अधिक सामान्य तरीके से अतुल्यकालिक समर्थन की समस्या को हल करते हैं, जो हमें पाइपलाइनों में सभी संभावित अभिव्यक्तियों का उपयोग करने की अनुमति देता है, न केवल await
, बल्कि typeof
, yield
और किसी भी अन्य ऑपरेटर।
बबेल दृश्य में प्रवेश करता है
जैसे ही तीनों प्रस्तावों पर सहमति बनी, हम इस निष्कर्ष पर पहुंचे कि इस तरह की चर्चाओं से प्रस्तावों के बीच गहरे अंतर्विरोधों का समाधान नहीं होगा। हमने तय किया कि वास्तविक कोड में वाक्यों का उपयोग करके डेवलपर्स से प्रतिक्रिया एकत्र करना सबसे अच्छा तरीका है। डेवलपर समुदाय में बैबेल की भूमिका को देखते हुए, हमने pipeline
ऑपरेटर प्लगइन में सभी तीन विकल्पों को जोड़ने का फैसला किया।
चूंकि सभी तीन वाक्यों के लिए पार्सिंग थोड़ा अलग है, लेकिन अलग-अलग, उनके समर्थन को पहले @babel/parser
(जो कि babylon
) में जोड़ा जाना चाहिए, और पार्सर को पता होना चाहिए कि किस प्रस्ताव का समर्थन किया जाना चाहिए। इस प्रकार, pipeline
ऑपरेटर प्लगइन को "proposal"
विकल्प की आवश्यकता है, दोनों बाबुल को पार्स करने के लिए और बाद के परिवर्तन के लिए।
हमने इस पर ऑनलाइन काम किया है क्योंकि हमें बैबल से पहले बैकवर्ड कम्पैटिबिलिटी को तोड़ने वाले सभी बदलाव करने की जरूरत है। अंत में, हम एक विन्यास विकल्प की आवश्यकता से छुटकारा पाने के लिए प्लगइन के लिए एक पाइपलाइन विकल्प को डिफ़ॉल्ट बनाना चाहते हैं।
इन सीमाओं को देखते हुए, हमने प्लगइन कॉन्फ़िगरेशन में एक विकल्प जोड़ने और इसे अनिवार्य बनाने का फैसला किया, जिससे उपयोगकर्ता यह तय कर सकें कि वे अपनी परियोजना में कौन से ऑफ़र का उपयोग करना चाहते हैं। जैसे ही एक विशिष्ट प्रस्ताव ऑपरेटर के विहित व्यवहार के रूप में चुना जाता है, हम विकल्प "proposal"
को अप्रचलित के रूप में चिह्नित करते हैं, और विहित विकल्प डिफ़ॉल्ट रूप से काम करेंगे। रद्द किए गए ऑफ़र के लिए समर्थन अगले प्रमुख संस्करण तक काम करेगा।
भाग लो
यदि आप प्रस्ताव की चर्चा में भाग लेना चाहते हैं, तो सभी चर्चाएँ सार्वजनिक हैं और आप उन्हें पाइपलाइन ऑपरेटर के प्रस्ताव के भंडार में पा सकते हैं। TC39 मीटिंग की एक प्रस्तुति आपकी सेवा में भी है। अंत में, आप ट्विटर पर जेम्स डिगिओया , जेएस चोई या डैनियल एहरनबर्ग का अनुसरण कर सकते हैं।
लेकिन इससे भी महत्वपूर्ण बात यह है कि जैसे ही pipeline
पर काम पूरा हो जाता है, इसे अपनी परियोजनाओं में आज़माएं! हम उत्तर देने के लिए नई सुविधाओं को जोड़ने पर भी काम कर रहे हैं, ताकि आप अपने कोड को अंतःक्रियात्मक रूप से जांच सकें हमें प्रतिक्रिया की आवश्यकता है, और वास्तविक कोड में इसका उपयोग करने से वास्तव में इसे इकट्ठा करने में मदद मिलेगी। @Babeljs को ट्वीट पोस्ट करें ।