यहां बताया गया है कि मैं आपको कैसे करना चाहिए।
श्रृंखला को विभाजित करना
क्योंकि दोनों फंक्शन amazingData का उपयोग कर रहे होंगे , यह उन्हें एक समर्पित फ़ंक्शन में रखने के लिए समझ में आता है। मैं आमतौर पर ऐसा करता हूं कि हर बार मैं कुछ डेटा का पुन: उपयोग करना चाहता हूं, इसलिए यह हमेशा एक फ़ंक्शन arg के रूप में मौजूद होता है।
जैसा कि आपका उदाहरण कुछ कोड चला रहा है, मुझे लगता है कि यह सब एक फ़ंक्शन के अंदर घोषित किया जाएगा। मैं इसे टोटो () कहूंगा । फिर हमारे पास एक और फंक्शन होगा जो afterSomething () और afterSomethingElse () दोनों चलेगा ।
function toto() {
return somethingAsync()
.then( tata );
}
आप यह भी ध्यान देंगे कि मैंने एक वापसी विवरण जोड़ा है क्योंकि यह आमतौर पर वादों के साथ जाने का तरीका है - आप हमेशा एक वादा वापस करते हैं ताकि हम आवश्यकता पड़ने पर जंजीर रख सकें। यहाँ, someAsync () अद्भुतता उत्पन्न करेगा और यह नए फ़ंक्शन के अंदर हर जगह उपलब्ध होगा।
अब यह नया कार्य क्या होगा जैसा आमतौर पर निर्भर करता है कि processAsync () भी अतुल्यकालिक है ?
processAsync एसिंक्रोनस नहीं
यदि processAsync () अतुल्यकालिक नहीं है, तो चीजों को ओवरक्लम्प्लीकेट करने का कोई कारण नहीं। कुछ पुराने अच्छे अनुक्रमिक कोड इसे बनाएंगे।
function tata( amazingData ) {
var processed = afterSomething( amazingData );
return afterSomethingElse( amazingData, processed );
}
function afterSomething( amazingData ) {
return processAsync( amazingData );
}
function afterSomethingElse( amazingData, processedData ) {
}
ध्यान दें कि इससे कोई फर्क नहीं पड़ता कि afterSomethingElse () कुछ async कर रहा है या नहीं। यदि ऐसा होता है, तो एक वादा वापस किया जाएगा और श्रृंखला जारी रह सकती है। यदि ऐसा नहीं है, तो परिणाम मूल्य वापस कर दिया जाएगा। लेकिन क्योंकि फ़ंक्शन को तब से बुलाया जाता है () , मूल्य वैसे भी एक वादा में लपेटा जाएगा (कम से कम कच्चे जावास्क्रिप्ट में)।
processAsync अतुल्यकालिक
यदि processAsync () असिंक्रोनस है, तो कोड थोड़ा अलग दिखेगा। यहाँ हम afterSomething () और afterSomethingElse () को कहीं और उपयोग नहीं करने जा रहे हैं।
function tata( amazingData ) {
return afterSomething()
.then( afterSomethingElse );
function afterSomething( /* no args */ ) {
return processAsync( amazingData );
}
function afterSomethingElse( processedData ) {
}
}
AfterSomethingElse () के लिए पहले जैसा है । यह अतुल्यकालिक हो सकता है या नहीं। एक वादा वापस कर दिया जाएगा, या एक सुलझे हुए वादे में लिपटे मूल्य।
आपकी कोडिंग शैली मेरे द्वारा उपयोग किए जाने के काफी करीब है, यही कारण है कि मैंने 2 साल बाद भी जवाब दिया। मैं हर जगह गुमनाम कार्यों का बहुत बड़ा प्रशंसक नहीं हूं। मुझे पढ़ना मुश्किल लगता है। भले ही यह समुदाय में काफी आम है। यह वैसा ही है जैसा कि हमने कॉलबैक-हेल को एक वादा-शोध-पत्र द्वारा बदल दिया ।
मैं तत्कालीन शॉर्ट में कार्यों का नाम रखना भी पसंद करता हूं । वे केवल वैसे भी स्थानीय रूप से परिभाषित होंगे। और अधिकांश समय वे एक और फ़ंक्शन को कहीं और परिभाषित करेंगे - इसलिए पुन: प्रयोज्य - काम करने के लिए। मैं केवल 1 पैरामीटर वाले कार्यों के लिए भी ऐसा करता हूं, इसलिए मुझे फ़ंक्शन हस्ताक्षर में एक पैरामीटर जोड़ने / निकालने पर फ़ंक्शन को अंदर और बाहर निकालने की आवश्यकता नहीं है।
खाने का उदाहरण
यहाँ एक उदाहरण है:
function goingThroughTheEatingProcess(plenty, of, args, to, match, real, life) {
return iAmAsync()
.then(chew)
.then(swallow);
function chew(result) {
return carefullyChewThis(plenty, of, args, "water", "piece of tooth", result);
}
function swallow(wine) {
return nowIsTimeToSwallow(match, real, life, wine);
}
}
function iAmAsync() {
return Promise.resolve("mooooore");
}
function carefullyChewThis(plenty, of, args, and, some, more) {
return true;
}
function nowIsTimeToSwallow(match, real, life, bobool) {
}
Promise.resolve () पर बहुत अधिक ध्यान न दें । यह बस एक त्वरित तरीका है एक सुलझा हुआ वादा करने का। इसके द्वारा मैं जो भी हासिल करने की कोशिश करता हूं वह सभी कोड मैं एक ही स्थान पर चल रहा है - केवल थेन के नीचे । अधिक वर्णनात्मक नाम के साथ अन्य सभी कार्य पुन: प्रयोज्य हैं।
इस तकनीक के साथ दोष यह है कि यह बहुत सारे कार्यों को परिभाषित कर रहा है। लेकिन यह एक आवश्यक दर्द है जिससे मैं डरता हूं ताकि सभी जगहों पर अनाम कार्य न हो सकें। और वैसे भी जोखिम क्या है: एक ढेर अतिप्रवाह? (मज़ाक!)
अन्य उत्तरों में परिभाषित सरणियों या वस्तुओं का उपयोग करना भी कारगर होगा। यह एक तरह से केविन रीड द्वारा प्रस्तावित उत्तर है ।
आप bind () या Promise.all () का भी उपयोग कर सकते हैं । ध्यान दें कि उन्हें अभी भी आपको अपना कोड विभाजित करने की आवश्यकता होगी।
बाँध का उपयोग करना
यदि आप अपने कार्यों को पुन: प्रयोज्य रखना चाहते हैं, लेकिन वास्तव में जो बहुत कम है, उसके अंदर रखने की आवश्यकता नहीं है, तो आप बाइंड () का उपयोग कर सकते हैं ।
function tata( amazingData ) {
return afterSomething( amazingData )
.then( afterSomethingElse.bind(null, amazingData) );
}
function afterSomething( amazingData ) {
return processAsync( amazingData );
}
function afterSomethingElse( amazingData, processedData ) {
}
इसे सरल रखने के लिए, बाँध () फ़ंक्शन के लिए आर्ग्स की सूची (पहले एक को छोड़कर ) को प्रीपेन्ड करेगा जब इसे कहा जाता है।
Promise.all का उपयोग करना
अपनी पोस्ट में आपने प्रसार () का उपयोग करने का उल्लेख किया है । मैंने आपके द्वारा उपयोग किए जा रहे ढांचे का उपयोग कभी नहीं किया, लेकिन यहां बताया गया है कि आपको इसका उपयोग करने में कैसे सक्षम होना चाहिए।
कुछ का मानना है कि Promise.all () सभी समस्याओं का समाधान है, इसलिए यह मेरे अनुमान के अनुसार उल्लेख के योग्य है।
function tata( amazingData ) {
return Promise.all( [ amazingData, afterSomething( amazingData ) ] )
.then( afterSomethingElse );
}
function afterSomething( amazingData ) {
return processAsync( amazingData );
}
function afterSomethingElse( args ) {
var amazingData = args[0];
var processedData = args[1];
}
आप Promise.all को डेटा पास कर सकते हैं () - सरणी की उपस्थिति पर ध्यान दें - जब तक वादे नहीं होंगे, लेकिन सुनिश्चित करें कि कोई भी वादा विफल नहीं होता है अन्यथा यह प्रसंस्करण बंद कर देगा।
और बदले से नए चर को परिभाषित करने की आर्ग तर्क, आप का उपयोग करने के लिए सक्षम होना चाहिए ) प्रसार ( बजाय तो () भयानक काम के सभी तरह के लिए।