दिलचस्प पोस्ट
एंड्रॉइड: 2 एमबी फ्री हीप के साथ 400KB फ़ाइल के साथ मेमोरी के बाहर बिटमैपफ़ीन्टर। एकोडस्ट्रीम () सीएसवी फ़ाइल आयात। नेट में संपादक / प्रदर्शन टेम्पलेट्स में अनुभागों का उपयोग करना एंड्रॉइड स्क्रीन पर कस्टम अर्रे लिस्ट को कैसे रोटेट करना है? मैं केवल एक Git रिपॉजिटरी की उपनिर्देशिका कैसे क्लोन करता हूं? मैं CSS या पाठ का उपयोग कैसे कर सकता हूँ? Angular.js में एक AJAX कॉल करने के लिए सबसे अच्छा अभ्यास क्या है? फ़ंक्शन पॉइंटर्स का क्या मतलब है? एक निर्देशिका की पूरी सामग्री php का उपयोग करके प्रतिलिपि करें जावा में ऑब्जेक्ट का आकार की गणना करें सम्मिलित करने का प्रयास करते समय त्रुटि, स्ट्रिंग या बाइनरी डेटा काट दिया जाएगा क्रोम एक्सटेंशन के अंतर्गत onClick काम नहीं कर रहा है लॉगकैट की आकार सीमा और इसकी क्षमता कैसे बदलनी है? पोस्ट बिल्ड ईवेंट का उपयोग करके एक प्रोजेक्ट से दूसरी फ़ाइल कॉपी करें … VS2010 टाइमआउट फ़ंक्शन यदि इसे खत्म करने में बहुत समय लगता है

कैसे jQuery का इस्तेमाल किया जा सकता है आस्थगित?

jQuery 1.5 नए डिफर्ड ऑब्जेक्ट और संलग्न विधियां ._Deferred.when , .Deferred और। ._Deferred

उन लोगों के लिए जो इसका इस्तेमाल नहीं करते थे। इसके लिए मैंने इसके स्रोत का .Deferred से पहले .Deferred

इन नए तरीकों के संभावित उपयोग क्या हैं, हम उन्हें पैटर्न के बारे में कैसे तय करते हैं?

मैंने पहले से ही एपीआई और स्रोत पढ़ लिया है , इसलिए मुझे पता है कि यह क्या करता है। मेरा प्रश्न यह है कि हम रोज़ कोड में इन नई सुविधाओं का कैसे उपयोग कर सकते हैं?

मेरे पास एक बफर वर्ग का एक सरल उदाहरण है जो क्रम में AJAX अनुरोध को कॉल करता है। (पिछले एक खत्म होने के बाद अगले एक शुरू)।

 /* Class: Buffer * methods: append * * Constructor: takes a function which will be the task handler to be called * * .append appends a task to the buffer. Buffer will only call a task when the * previous task has finished */ var Buffer = function(handler) { var tasks = []; // empty resolved deferred object var deferred = $.when(); // handle the next object function handleNextTask() { // if the current deferred task has resolved and there are more tasks if (deferred.isResolved() && tasks.length > 0) { // grab a task var task = tasks.shift(); // set the deferred to be deferred returned from the handler deferred = handler(task); // if its not a deferred object then set it to be an empty deferred object if (!(deferred && deferred.promise)) { deferred = $.when(); } // if we have tasks left then handle the next one when the current one // is done. if (tasks.length > 0) { deferred.done(handleNextTask); } } } // appends a task. this.append = function(task) { // add to the array tasks.push(task); // handle the next task handleNextTask(); }; }; 

मैं प्रदर्शनों और संभावित उपयोगों की तलाश कर रहा हूं। .Deferred और। .when

यह भी उदाहरण के देखने के लिए प्यारा होगा।

उदाहरण के लिए नए jQuery.ajax स्रोत से jQuery.ajax है धोखाधड़ी।

बाउंटी: हमें बताएं कि कौन से तकनीकें उपलब्ध हैं, जब हम एक सार को सिंक्रोनस या एसिंक्रोनस तरीके से किया जाए या नहीं।

वेब के समाधान से एकत्रित समाधान "कैसे jQuery का इस्तेमाल किया जा सकता है आस्थगित?"

सबसे अच्छा उपयोग करने वाला मामला जो मैं सोच सकता हूं वह AJAX प्रतिक्रिया कैशिंग में है। इस विषय पर रेबेका मर्फ़े की परिचय पोस्ट का एक संशोधित उदाहरण है:

 var cache = {}; function getData( val ){ // return either the cached value or jqXHR object wrapped Promise return $.when( cache[ val ] || $.ajax('/foo/', { data: { value: val }, dataType: 'json', success: function( resp ){ cache[ val ] = resp; } }) ); } getData('foo').then(function(resp){ // do something with the response, which may // or may not have been retrieved using an // XHR request. }); 

असल में, यदि मूल्य पहले से ही कैश से तुरंत वापस आने से पहले एक बार अनुरोध किया गया है। अन्यथा, एक AJAX अनुरोध डेटा को प्राप्त करता है और इसे कैश में जोड़ता है। $.when / $.when इसमें से किसी के बारे में परवाह नहीं है; आप सभी के बारे में चिंतित होने की जरूरत है प्रतिक्रिया का उपयोग कर रहा है, जो कि दोनों मामलों में। तब .then() हैंडलर को पारित किया गया है। jQuery.when() एक गैर-वादा / एक पूर्ण रूप में .done() , किसी भी .done() या .done() को श्रृंखला पर निष्पादित करने के बाद .done() करता है।

डिफरड एकदम सही होते हैं जब कार्य असिंक्रोनस रूप से संचालित हो सकता है या नहीं, और आप इस शर्त को उस कोड से बाहर करना चाहते हैं।

$.when का उपयोग करते हुए एक अन्य वास्तविक दुनिया उदाहरण $.when सहायक:

 $.when($.getJSON('/some/data/'), $.get('template.tpl')).then(function (data, tmpl) { $(tmpl) // create a jQuery object out of the template .tmpl(data) // compile it .appendTo("#target"); // insert it into the DOM }); 

एहेंद के उत्तर के रूप में यहां एक AJAX कैश का थोड़ा अलग कार्यान्वयन है।

जैसा कि भाग्य में बताया गया है राइस के अनुवर्ती सवाल , अगर ईमान के कार्यान्वयन में उनमें से एक के लौटने से पहले अनुरोध किए गए तो कई समान अनुरोधों को रोक नहीं पाया। अर्थात्,

 for (var i=0; i<3; i++) { getData("xxx"); } 

सबसे अधिक संभावना 3 AJAX अनुरोधों में परिणाम होगा यदि "xxx" के लिए परिणाम पहले से ही कैश नहीं किया गया है।

इसके परिणाम के बजाय अनुरोध डिफरेड को कैश करके इसे हल किया जा सकता है:

 var cache = {}; function getData( val ){ // Return a promise from the cache (if available) // or create a new one (a jqXHR object) and store it in the cache. var promise = cache[val]; if (!promise) { promise = $.ajax('/foo/', { data: { value: val }, dataType: 'json' }); cache[val] = promise; } return promise; } $.when(getData('foo')).then(function(resp){ // do something with the response, which may // or may not have been retreived using an // XHR request. }); 

एक स्थगित एक म्यूट एक्स के स्थान पर इस्तेमाल किया जा सकता है। यह अनिवार्य रूप से एकाधिक एजेक्स उपयोग परिदृश्यों के समान है।

म्युटेक्स

 var mutex = 2; setTimeout(function() { callback(); }, 800); setTimeout(function() { callback(); }, 500); function callback() { if (--mutex === 0) { //run code } } 

स्थगित

 function timeout(x) { var dfd = jQuery.Deferred(); setTimeout(function() { dfd.resolve(); }, x); return dfd.promise(); } jQuery.when( timeout(800), timeout(500)).done(function() { // run code }); 

केवल एक म्यूट एक्स के रूप में डिफर्ड का उपयोग करते समय, प्रदर्शन प्रभावों के लिए देखें (http://jsperf.com/deferred-vs-mutex/2) यद्यपि सुविधा, साथ ही डिफर्ड द्वारा दिए गए अतिरिक्त लाभ अच्छी तरह से लायक हैं, और वास्तविक (उपयोगकर्ता आधारित ईवेंट आधारित) उपयोग में प्रदर्शन प्रभाव को ध्यान नहीं दिया जाना चाहिए।

यह एक आत्म-प्रचार का उत्तर है, लेकिन मैंने कुछ महीने इस पर शोध किया और परिणामों को प्रस्तुत किया, जो jQuery कॉन्फ्रेंस, सैन फ्रांसिस्को 2012 में हुआ।

यहां चर्चा का एक निशुल्क वीडियो है:

http://www.confreaks.com/videos/993-jqcon2012-i-promise-to-show-you-when-to-use-deferreds

एक और प्रयोग जिसका मैंने अच्छा उद्देश्य रख दिया है वह कई स्रोतों से डेटा प्राप्त कर रहा है। नीचे दिए गए उदाहरण में, मैं क्लाइंट और एक REST सर्वर के बीच मान्यता के लिए मौजूदा, मौजूदा JSON स्कीमा ऑब्जेक्ट्स का उपयोग कर रहा हूं। इस मामले में, मैं नहीं चाहता कि ब्राउजर-साइड एप्लिकेशन को सभी स्कीमा भरी हुई होने से पहले डेटा लोड करना शुरू करना चाहिए। $ .when.apply ()। फिर () इस के लिए एकदम सही है। त्रुटि शर्तों के लिए निगरानी के लिए फिर (fn1, fn2) का उपयोग करने पर संकेत के लिए रेनोस के लिए धन्यवाद।

 fetch_sources = function (schema_urls) { var fetch_one = function (url) { return $.ajax({ url: url, data: {}, contentType: "application/json; charset=utf-8", dataType: "json", }); } return $.map(schema_urls, fetch_one); } var promises = fetch_sources(data['schemas']); $.when.apply(null, promises).then( function () { var schemas = $.map(arguments, function (a) { return a[0] }); start_application(schemas); }, function () { console.log("FAIL", this, arguments); }); 

किसी भी प्रकार की गणना के लिए कैश को लागू करने के लिए Deferred का उपयोग करने वाला एक और उदाहरण (आमतौर पर कुछ प्रदर्शन-गहन या लंबे समय से चलने वाले कार्य):

 var ResultsCache = function(computationFunction, cacheKeyGenerator) { this._cache = {}; this._computationFunction = computationFunction; if (cacheKeyGenerator) this._cacheKeyGenerator = cacheKeyGenerator; }; ResultsCache.prototype.compute = function() { // try to retrieve computation from cache var cacheKey = this._cacheKeyGenerator.apply(this, arguments); var promise = this._cache[cacheKey]; // if not yet cached: start computation and store promise in cache if (!promise) { var deferred = $.Deferred(); promise = deferred.promise(); this._cache[cacheKey] = promise; // perform the computation var args = Array.prototype.slice.call(arguments); args.push(deferred.resolve); this._computationFunction.apply(null, args); } return promise; }; // Default cache key generator (works with Booleans, Strings, Numbers and Dates) // You will need to create your own key generator if you work with Arrays etc. ResultsCache.prototype._cacheKeyGenerator = function(args) { return Array.prototype.slice.call(arguments).join("|"); }; 

कुछ (नकली भारी) गणना करने के लिए इस वर्ग का उपयोग करने का एक उदाहरण यहां दिया गया है:

 // The addingMachine will add two numbers var addingMachine = new ResultsCache(function(a, b, resultHandler) { console.log("Performing computation: adding " + a + " and " + b); // simulate rather long calculation time by using a 1s timeout setTimeout(function() { var result = a + b; resultHandler(result); }, 1000); }); addingMachine.compute(2, 4).then(function(result) { console.log("result: " + result); }); addingMachine.compute(1, 1).then(function(result) { console.log("result: " + result); }); // cached result will be used addingMachine.compute(2, 4).then(function(result) { console.log("result: " + result); }); 

उसी अंतर्निहित कैश का उपयोग एजेक्स अनुरोध को कैश करने के लिए किया जा सकता है:

 var ajaxCache = new ResultsCache(function(id, resultHandler) { console.log("Performing Ajax request for id '" + id + "'"); $.getJSON('http://jsfiddle.net/echo/jsonp/?callback=?', {value: id}, function(data) { resultHandler(data.value); }); }); ajaxCache.compute("anID").then(function(result) { console.log("result: " + result); }); ajaxCache.compute("anotherID").then(function(result) { console.log("result: " + result); }); // cached result will be used ajaxCache.compute("anID").then(function(result) { console.log("result: " + result); }); 

आप इस jsFiddle में ऊपर कोड के साथ खेल सकते हैं

1) कॉलबैक का आदेश दिया गया निष्पादन सुनिश्चित करने के लिए इसका उपयोग करें:

 var step1 = new Deferred(); var step2 = new Deferred().done(function() { return step1 }); var step3 = new Deferred().done(function() { return step2 }); step1.done(function() { alert("Step 1") }); step2.done(function() { alert("Step 2") }); step3.done(function() { alert("All done") }); //now the 3 alerts will also be fired in order of 1,2,3 //no matter which Deferred gets resolved first. step2.resolve(); step3.resolve(); step1.resolve(); 

2) ऐप की स्थिति को सत्यापित करने के लिए इसका उपयोग करें:

 var loggedIn = logUserInNow(); //deferred var databaseReady = openDatabaseNow(); //deferred jQuery.when(loggedIn, databaseReady).then(function() { //do something }); 

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

 var resizeQueue = new $.Deferred(); //new is optional but it sure is descriptive resizeQueue.resolve(); function resizeAlgorithm() { //some resize code here } $(window).resize(function() { resizeQueue.done(resizeAlgorithm); }); 

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

आप इसे किसी भी तीसरे पक्षीय पुस्तकालयों के साथ एकीकृत कर सकते हैं जो JQuery का उपयोग करता है

ऐसी एक लाइब्रेरी बैकबोन है, जो वास्तव में अपने अगले संस्करण में डिफर्ड को समर्थन देने जा रही है। मैंने इसके बारे में अपने ब्लॉग पर भी बात की है

मैंने अभी वास्तविक कोड में डिफर्ड का उपयोग किया है प्रोजेक्ट jQuery टर्मिनल में मेरे पास फ़ंक्शन exec है जो कि कॉल कमांड को यूज़र द्वारा परिभाषित करता है (जैसे वह इसमें प्रवेश कर रहा था और एंटरिंग करता था), मैंने एफ़आई में डिफरेड्स जोड़ दिया है और एआरएल्स के साथ call exec। इस तरह:

 terminal.exec('command').then(function() { terminal.echo('command finished'); }); 

या

 terminal.exec(['command 1', 'command 2', 'command 3']).then(function() { terminal.echo('all commands finished'); }); 

आदेश async कोड चला सकते हैं, और exec को उपयोगकर्ता कोड को क्रम में कॉल करने की आवश्यकता है। मेरी पहली एपीआई का इस्तेमाल जोड़ी को रोकना / फिर से शुरू करना और नए एपीआई में मैं उन स्वचालित कॉल करता हूं जब उपयोगकर्ता वापसी वादा करता है। तो उपयोगकर्ता कोड केवल उपयोग कर सकता है

 return $.get('/some/url'); 

या

 var d = new $.Deferred(); setTimeout(function() { d.resolve("Hello Deferred"); // resolve value will be echoed }, 500); return d.promise(); 

मैं इस तरह कोड का उपयोग करता हूँ:

 exec: function(command, silent, deferred) { var d; if ($.isArray(command)) { return $.when.apply($, $.map(command, function(command) { return self.exec(command, silent); })); } // both commands executed here (resume will call Term::exec) if (paused) { // delay command multiple time d = deferred || new $.Deferred(); dalyed_commands.push([command, silent, d]); return d.promise(); } else { // commands may return promise from user code // it will resolve exec promise when user promise // is resolved var ret = commands(command, silent, true, deferred); if (!ret) { if (deferred) { deferred.resolve(self); return deferred.promise(); } else { d = new $.Deferred(); ret = d.promise(); ret.resolve(); } } return ret; } }, 

dalyed_commands को फिर से शुरू करने के लिए उपयोग किया जाता है जो कि सभी dalyed_commands के साथ कॉल फिर से कॉल करता है

और कमांड फ़ंक्शन का हिस्सा (मैंने संबंधित भागों को नहीं छीन लिया है)

 function commands(command, silent, exec, deferred) { var position = lines.length-1; // Call user interpreter function var result = interpreter.interpreter(command, self); // user code can return a promise if (result != undefined) { // new API - auto pause/resume when using promises self.pause(); return $.when(result).then(function(result) { // don't echo result if user echo something if (result && position === lines.length-1) { display_object(result); } // resolve promise from exec. This will fire // code if used terminal::exec('command').then if (deferred) { deferred.resolve(); } self.resume(); }); } // this is old API // if command call pause - wait until resume if (paused) { self.bind('resume.command', function() { // exec with resume/pause in user code if (deferred) { deferred.resolve(); } self.unbind('resume.command'); }); } else { // this should not happen if (deferred) { deferred.resolve(); } } } 

एहेंड्स द्वारा जवाब काम नहीं करेगा, क्योंकि यह प्रतिक्रिया डेटा कैश करता है यह जेकएक्सएचआर को कैश करना चाहिए जो कि एक वादा भी है यहां सही कोड है:

 var cache = {}; function getData( val ){ // return either the cached value or an // jqXHR object (which contains a promise) return cache[ val ] || $.ajax('/foo/', { data: { value: val }, dataType: 'json', success: function(data, textStatus, jqXHR){ cache[ val ] = jqXHR; } }); } getData('foo').then(function(resp){ // do something with the response, which may // or may not have been retreived using an // XHR request. }); 

जूलियन डी द्वारा जवाब सही काम करेगा और बेहतर समाधान है।