8

$.Deferred का उपयोग करने के बाद से मैंने इस परिदृश्य में कुछ बार भाग लिया है: मेरे पास मूल्यों की एक सूची है जिसमें से प्रत्येक में एक अलग ऑब्जेक्ट उत्पन्न होता है और मैं कॉलबैक निष्पादित करना चाहता हूं स्थगित वस्तुओं का समाधान किया जाता है।Deferred ऑब्जेक्ट्स के Arrays से निपटने

var urls = [ 'foo.com', 'bar.com', 'baz.com', 'qux.com' ], 
    defers = [], defer; 

for(var i = 0, j = urls.length; i < j; i++){ 
    defer = $.ajax({ 
     url: 'http://' + urls[ i ] 
    }); 

    defers.push(defer); 
} 

$.when.apply(window, defers).done(function(){ 
    // Do Something 
}); 

मेरे उदाहरण में कोड की तुलना में अधिक सुरुचिपूर्ण समाधान है:

एक और अधिक ठोस उदाहरण कुछ इस तरह हो सकता है?

+2

आपको क्यों लगता है कि यह सुरुचिपूर्ण नहीं है? – topek

+0

तीसरे बार इस तरह के कोड लिखने के बाद मुझे लगता है कि यह एक काफी आम परिदृश्य है और इसे बेहतर तरीके से डिफरर्ड ऑब्जेक्ट्स फ्रेमवर्क द्वारा संभाला जा सकता है जिसे मैं बस देख रहा था। –

उत्तर

3

हां, आपको किसी लूप में लुकअप वैल्यू का संदर्भ कभी नहीं देना चाहिए। हमेशा एक प्रति बनाओ।

var urls = [ 'foo.com', 'bar.com', 'baz.com', 'qux.com' ], 
    defers = [], defer; 

var urlsLength = urls.length; 
for(var i = 0, j = urlsLength; i < j; i++){ 
    defer = $.ajax({ 
     url: 'http://' + urls[ i ] 
    }); 

    defers.push(defer); 
} 

$.when.apply(window, defers).done(function(){ 
    // Do Something 
}); 

लेकिन गंभीरता से, मैं सिर्फ जोशिन हूं। वह कोड चट्टानों। इसके साथ बने रहें।

+1

आप लुकअप वैल्यू के बारे में सही हैं लेकिन इसे घोषणा में रखते हैं (यानी 'var i = 0, j = urls.length') इसे कैश करता है। आप जो बचाना चाहते हैं वह तुलना में है (यानी 'i

0

यहाँ, एक सहायक समारोह मैं LoadInitialData बुलाया लिखा है यह एक और अधिक सुरुचिपूर्ण तरीका इस उदाहरण लिखने के लिए इस LoadInitialData(urlArray, dataReturnedArray, callback)

/// 
/// 1. The magical function LoadInitialData 
/// 

      /// 
      /// <summary> 
      /// This functions allows you to fire off a bunch of ajax GET requests and run a callback function when 
      /// all the requests come back that contains an array of all your ajax success data 
      /// </summary> 
      /// <params> 
      ///   urlArray - an array of urls to be looped and ajaxed 
      /// dataReturnedArray - this array will contain all data returned from your ajax calls. Its stuctured like this 
      ///   [{url: "http//site.com/1", "data": "your data"}, {url: "http//site.com/2", "data": "your data"}] 
      ///   dataReturnedArray[0] is data from call 1, dataReturnedArray[1] is data from call 2 etc. It might be a 
      ///   good idea to pass in a global array so you can use this data throughout your application. 
      ///  callback - a function that runs after all ajax calles are done, dataReturnedArray is available in the callback 
      /// </parms> 
      /// 
      function LoadInitialData(urlArray, dataReturnedArray, callback){ 
       // set up a deffered promise to fire when all our async calls come back 
       var urls = urlArray, defers = [], defer; 
        var urlsLength = urls.length; 
        for(var i = 0, j = urlsLength; i < j; i++){ 
         var u = urls[ i ]; 
          defer = $.ajax({ 
          type : "GET", 
          dataType : "jsonp", 
          url: u, 
          success: function(data){ 
           dataReturnedArray.push({ 
             url: u, 
             data: data 
           }); 
          } 
         }); 
         defers.push(defer); 
        } 
        $.when.apply(window, defers).then(function(){ 
          // Do Something now that we have all the data 
         console.log("done fetching all data"); 
         callback(dataReturnedArray); 
        }); 
      } 



/// 
/// 2. Your config…. urlArray, dataReturnedArray, callback 
/// 

     var app = app || {}; 
     app.data = []; // will hold the fetched data 
     var urlArr = ["http://site.com/2", "http://site.com/2"]; // the urls to get data from 


     // function to call once all the data is loaded 
     callback = function(data){ 

      // data cleansing 
      var tblData = [];       
      $.each(data, function(key, value){ 
        $.each(value.data, function(key, value){ 
          tblData.push(value); 
        }); 
      }); 

      $("#loader").hide(); 
     }; 


/// 
/// 3. Kick it all off! 
/// 

     // show a loader here 
     $("#loader").show(); 

     // fire off the code to fetch the initial data 
     LoadInitialData(urlArr, app.data, callback); 
3

की तरह कहा जा सकता है सरणी नक्शा समारोह के साथ है (या jQuery के $ .map):

var urls = [ 'foo.com', 'bar.com', 'baz.com', 'qux.com' ]; 

var defers = urls.map(function(url) { 
    return $.ajax({ 
     url: 'http://' + url 
    }); 
}); 

$.when.apply(window, defers).done(function(){ 
    // Do Something 
}); 

आप अपने स्वयं के "whenDone" और "fetchURL" कार्यों रोल कर सकते हैं:

Array.prototype.whenDone = function(callback){ 
    return $.when.apply(window, this).done(callback); 
} 

function fetchURL(url){ 
    return $.ajax({ 
     url: 'http://' + url 
    }); 
} 

var urls = [ 'foo.com', 'bar.com', 'baz.com', 'qux.com' ];  

urls.map(fetchUrl).whenDone(function(){ 
    // Do Something 
}); 
+0

मुझे 'Array.prototype.map' के उपयोग को पसंद है। वह क्लीनर है। –

संबंधित मुद्दे