2012-06-18 1 views
5

के साथ पहले उपलब्ध डेटा स्रोत खोजें इसलिए मुझे एक साक्षात्कार में यह पूछा गया, लेकिन यह एक अच्छा उपयोग केस लाया। मान लें कि आपके पास डेटा स्रोतों का एक गुच्छा है। आप पहले उपलब्ध एक को ढूंढना चाहते हैं और इसे संसाधित करना चाहते हैं और बाकी को अनदेखा करना चाहते हैं।jQuery डीफ़र्ड

तो जैसे कुछ:

var datasources = new Array("somedatabase1/pizza","somedatabase2/beer","somedatabase3/llama"); 
var dfds = new Array(); 
$.each(datasources,function(source){ 
    dfds.push($.getJSON(source)); 
}); 

$.when(dfds).done(function(){alert("they are all done");}); 

पर ध्यान न दें कि मैं वास्तव में जब एक सरणी (शायद यह करता है) स्वीकार नहीं लगता। यह निश्चित रूप से तब तक इंतजार करेगा जब तक कि वे पूरी नहीं हो जाते। मैं कुछ कोड ढूंढ रहा हूं जो इसे एक तक इंतजार कर देगा, उनमें से कोई भी किया जाएगा, और फिर दूसरों के बारे में चिंता न करें।

मुझे सूचित किया गया कि यह केवल रिकर्सिव रूप से काम करेगा।

+0

वे सभी एक ही समय में एक दूसरे जब पहली विफल रही आरंभ करना चाहिए, या? – Bergi

+0

@ बर्गि मुझे लगता है कि या तो काम करेगा, मुझे लगता है कि दोनों विभिन्न उपयोग मामलों में इष्टतम हैं। – Parris

+0

हां, लेकिन उनकी अवधारणा बहुत अलग है। तो आपको किसकी आवश्यकता है? – Bergi

उत्तर

3

यह रिकर्सन का उपयोग नहीं करता है लेकिन एकाधिक डेटा स्रोतों से प्राप्त करने की आवश्यकता को फिट करता है और केवल पहले प्रतिक्रिया की प्रतिक्रिया देता है जो सफल प्रतिक्रिया देता है।

http://jsfiddle.net/mNJ6D/

function raceToIt(urls) { 
    var deferred = $.Deferred(), 
     promises; 

    function anyComplete(data) { 
     if (!deferred.isResolved()) { 
      deferred.resolveWith(this, [data]); 
      promises.forEach(function(promise) { 
       promise.abort(); 
      }); 
     } 
    } 
    promises = urls.map(function(url) { 
     return $.getJSON(url).then(anyComplete); 
    }); 
    return deferred.promise(); 
} 
raceToIt(["/echo/json/", "/echo/json/", "/echo/json/"]).then(function(data) { 
    console.log(data); 
});​ 
+0

यह वास्तव में बहुत बढ़िया है, और यह आपको एक बार में सभी को शुरू करने देता है! शायद अन्य लुकअप को रोकने का भी एक तरीका है। – Parris

+1

@ पेरिस सुनिश्चित करें, बस कहीं भी स्थगित स्टोर करें और 'anycomplete' हैंडलर में 'abort'' पर कॉल करें। मैंने इसे संपादित किया है। – Esailija

1

मैं जो उलट अर्थ विज्ञान के साथ $.when() का एक और संस्करण प्रदान करता है एक प्लगइन बनाया है। यह $.when() के वास्तविक jQuery कार्यान्वयन से संशोधित है, इसलिए यह मूल के समान ही है, सिवाय इसके कि यह पहले resolve डी वादे के लिए इंतजार कर रहा है, या सभी reject एड होने का वादा किया है।

बस आप jQuery लोड के बाद सही में इस कोड को छोड़:

(function($) { 
    $.reverseWhen = function(subordinate /* , ..., subordinateN */) { 
    var i = 0, 
     rejectValues = Array.prototype.slice.call(arguments), 
     length = rejectValues.length, 

     // the count of uncompleted subordinates 
     remaining = length !== 1 || (subordinate && jQuery.isFunction(subordinate.promise)) ? length : 0, 

     // the master Deferred. If rejectValues consist of only a single Deferred, just use that. 
     deferred = remaining === 1 ? subordinate : jQuery.Deferred(), 

     // Update function for both reject and progress values 
     updateFunc = function(i, contexts, values) { 
     return function(value) { 
      contexts[ i ] = this; 
      values[ i ] = arguments.length > 1 ? Array.prototype.slice.call(arguments) : value; 
      if(values === progressValues) { 
      deferred.notifyWith(contexts, values); 
      } else if (!(--remaining)) { 
      deferred.rejectWith(contexts, values); 
      } 
     }; 
     }, 

     progressValues, progressContexts, rejectContexts; 

    // add listeners to Deferred subordinates; treat others as rejected 
    if (length > 1) { 
     progressValues = new Array(length); 
     progressContexts = new Array(length); 
     rejectContexts = new Array(length); 
     for (; i < length; i++) { 
     if (rejectValues[ i ] && jQuery.isFunction(rejectValues[ i ].promise)) { 
      rejectValues[ i ].promise() 
      .done(deferred.resolve) 
      .fail(updateFunc(i, rejectContexts, rejectValues)) 
      .progress(updateFunc(i, progressContexts, progressValues)); 
     } else { 
      --remaining; 
     } 
     } 
    } 

    // if we're not waiting on anything, reject the master 
    if (!remaining) { 
     deferred.rejectWith(rejectContexts, rejectValues); 
    } 

    return deferred.promise(); 
    }; 
})(jQuery);