अतुल्यकालिक तुल्यकालन। JSDeferred

हाल ही में, एसिंक्रोनस कॉल के साथ काम करने पर कई लेख हाइब्रिड पर दिखाई दिए हैं ( सभी अतुल्यकालिक कॉल के बाद , एसिंक्रोनस कॉल को सिंक्रनाइज़ करना। WaitSync )। लेकिन करीब से जांच करने पर, उनके आवेदन का दायरा कम होता है क्योंकि ये विधियाँ सभी समस्याओं का समाधान नहीं करती हैं।

लेकिन पहले, आइए इन बहुत समस्याओं की पहचान करने की कोशिश करें जो हम अतुल्यकालिक कॉल के साथ काम करते समय सामना करते हैं।



और प्रयोगों के लिए हम एक उदाहरण * का चयन करते हैं, जिसमें आपको एक उपयोगकर्ता प्रोफ़ाइल, नए संदेश और उसके बाद ही पृष्ठ प्रदर्शित करने का अनुरोध करने की आवश्यकता होती है। तुल्यकालिक निष्पादन का उपयोग, समाधान यह होगा:

var profile = get_profile(user); var msgs = get_msgs(user); render_page({'profile' : profile, 'msgs' : msgs});
      
      





* सभी उदाहरण सिंथेटिक हैं, उन्होंने सार पर ध्यान केंद्रित करने के लिए कई बिंदुओं को याद किया



समस्याएं हैं:



1. बड़ा कोड नेस्टिंग



हमारे उदाहरण का एक अतुल्यकालिक संस्करण इस तरह दिखता है:

 var params = {}; get_profile(user, function(profile){ params['profile'] = profile; get_msgs(user, function(msgs){ params['msgs'] = msgs; render_page(params); }) })
      
      





बड़ी संख्या में नेस्टेड प्रश्नों के साथ, ऐसा रिकॉर्ड खराब पठनीय और डीबग करना मुश्किल हो जाता है।



2. समानांतर कॉल



हमारे उदाहरण में, सभी कॉल क्रमिक रूप से किए जाते हैं, लेकिन उनमें से सभी केवल उपयोगकर्ता के तर्क से बंधे होते हैं और एक दूसरे से स्वतंत्र होते हैं, इसलिए मैं उन्हें पेज पीढ़ी को गति देने के लिए समानांतर में चलाना चाहूंगा।



आमतौर पर वे ऐसा करते हैं:

 var params = { 'profile' : null, 'msgs' : null } render_page(){ if (params['profile'] && params['msgs'] !== null){ do_render_page(); } } get_profile(user, function(data){ params['profile'] = data; render_page(); }) get_msgs(user, function(data){ params['msgs'] = data; render_page(); })
      
      





सभी अतुल्यकालिक कॉल और अतुल्यकालिक कॉल के सिंक्रनाइज़ेशन के बाद इस समस्या का वर्णन किया गया है WaitSync



उपरोक्त विषयों से विधि का उपयोग करते हुए, समस्या का समाधान इस तरह दिखाई देगा:

 var process = render_page.after('profile', 'new_msgs'); get_profile(user, process.profile); get_msgs(user, process.new_msgs );
      
      







3. हैंडलिंग में त्रुटि



मान लें कि हमें get_profile () या get_msgs () निष्पादित करते समय हुई त्रुटियों या अपवादों को संभालने की आवश्यकता है



तुल्यकालिक कोड के लिए, सब कुछ बहुत सरल है:

 try{ var msgs = get_msgs(user); var profile = get_profile(user); if (profile){ render_page({'profile' : profile, 'msgs' : msgs}); }else{ redirect_to_login_page(); } }catch(e){ show_error_msg(e); }
      
      







अतुल्यकालिक कॉल के लिए, त्रुटियों को कॉलबैक के पैरामीटर के रूप में पारित किया जा सकता है या एक अलग कॉलबैक का उपयोग किया जा सकता है। अपवाद जो जानबूझकर / जानबूझकर get_profile () या get_msgs () के अंदर होते हैं, उन्हें बाहर से पकड़ना इतना आसान नहीं होगा।



4. व्यापकता



यह समस्या पहले तीन के परिणामस्वरूप उत्पन्न होती है।

मान लीजिए कि हम हाल की टिप्पणियों की एक और सूची, हाल ही में पढ़े गए विषय, रेटिंग को लगातार प्राप्त करना चाहते हैं। फिर पहले पैराग्राफ से उदाहरण एक भयानक राक्षस में बदल जाएगा।

 var params = {}; get_profile(user, function(profile){ params['profile'] = profile; get_msgs(user, function(msgs){ params['msgs'] = msgs; get_last_comments(user, function(comments){ params['comments'] = comments; get_last_readed_topics(user, function(topics){ params['topics'] = topics; get_rating(user, function(rating){ params['rating'] = rating; render_page(params) }) }) }) }) })
      
      





यदि हम त्रुटि से निपटने के लिए कॉलबैक जोड़ते हैं, तो हम सबसे अधिक संभावना प्रोग्रामर्स द्वारा शापित होंगे, जिन्हें आपके कोड को समझना पड़ सकता है।



हमारी मदद करने की जल्दी में ... JSDeferred



और अब मैं उन लोगों से परिचय करना चाहता हूं जो कि डीआरएफ़आरडी तंत्र के कार्यान्वयन में से किसी एक से परिचित नहीं हैं, जिसका नाम है जेएससीफेर्रेड । यह लाइब्रेरी आपको सिंक्रोनस के रूप में अतुल्यकालिक कॉल के साथ काम करने की अनुमति देती है। अब हमारी चार समस्याओं का समाधान क्या दिखेगा:



1. बड़े कोड नेस्टिंग (समाधान)



कॉलबैक को जंजीरों से बदल दिया जाता है। चेन लिंक को निष्पादित करने का परिणाम एक तर्क के साथ अगले लिंक पर जाता है।

 var params = {}; next(function(){ return get_profile(user) }). next(function(profile){ params['profile'] = profile }). next(function(){ return get_msgs(user) }). next(function(msgs){ params['msgs'] = msgs; render_page(params); })
      
      







2. समानांतर कॉल (समाधान)



अगले लिंक को समानांतर रिटर्न परिणामों में सभी अनुरोधों के बाद ही कहा जाता है। एक तर्क समानांतर निष्पादन परिणामों की एक सरणी पारित करेगा।

 parallel([ get_profile(user), get_msgs(user) ]). next(function(params){ render_page({'profile' : params[0], 'msgs' : params[1]}) //    // render_page.apply(this, params); })
      
      







3. त्रुटि से निपटने (समाधान)



यदि लिंक में एक अपवाद होता है, तो आंदोलन के क्रम में अगला लिंक त्रुटि कहा जाएगा। पैरामीटर फेंक के माध्यम से फेंक दिए गए संदेश को पारित करता है;

 var params = {}; next(function(){ return get_profile(user) }). error(function(e){ redirect_to_login_page(); }). next(function(profile){ params['profile'] = profile }). next(function(){ return get_msgs(user) }). error(function(e){ show_error_msg(e); }). next(function(msgs){ params['msgs'] = msgs; render_page(params); })
      
      







4. एक्स्टेंसिबिलिटी (समाधान)



नया हैंडलर चरण जोड़ने के लिए यहां सब कुछ बहुत स्पष्ट होना चाहिए - बस श्रृंखला में एक नया तत्व जोड़ें।



अति सूक्ष्म अंतर



हमने मुख्य समस्याओं के समाधान की जांच की, और अब एक बारीकियों के बारे में। अतुल्यकालिक कार्यों / विधियों को एक विशेष तरीके से तैयार किया जाना चाहिए:

1. उन्हें एक आस्थगित वस्तु वापस करनी चाहिए

2. श्रृंखला के साथ आगे बढ़ने के लिए, आस्थगित ऑब्जेक्ट की कॉल () विधि को कॉल करें

3. एक त्रुटि उत्पन्न करने के लिए - विफल कॉल () विधि को स्थगित कर दिया

प्रलेखन में विधियों की एक पूरी सूची मिल सकती है।



यानी XmlHttpRequest का उपयोग करके एक संशोधित फ़ंक्शन इस तरह दिखाई देगा:

 function http_get(url) { var d = Deferred(); var xhr = new XmlHttpRequest(); xhr.open("GET", url, true); xhr.onreadystatechange = function() { if (xhr.readyState != 4) return; if (xhr.status==200){ d.call(xhr.responseText); } else { d.fail(xhr.statusText); } } xhr.send(null); return d; }
      
      







निष्कर्ष



सिंगल AJAX अनुरोधों के लिए, Deferred की उपयोगिता संदिग्ध है, लेकिन यदि आप बहुत अधिक असंगत कॉल का उपयोग करते हैं, या यदि परियोजना में अधिक बढ़ने और अधिक जटिल बनने की क्षमता है, तो यह Deferred पर ध्यान देने के लिए समझ में आता है। यह एक बहुत शक्तिशाली तंत्र है जिसके साथ आप लिंक के समानांतर समानांतर / अनुक्रमिक निष्पादन, त्रुटि से निपटने और रीडिंग कोड के साथ यह सब करने के साथ बड़ी श्रृंखला बना सकते हैं।



अनुशंसित पढ़ना



1. गितुब पर JSDeferred

2. JSDeferred परियोजना पृष्ठ

3. अतुल्यकालिक कॉल नेस्टेड। विस्तार से आस्थगित वस्तु

4. dojo.Deferred

5. JQuery के आस्थगित / JSDeferred



All Articles