2013-01-06 39 views
5

यह संभव है कि AJAX फ़ंक्शंस के मेरे हिस्से पर एक गलतफहमी हो, लेकिन मेरे पास ऐसी स्थिति है जहां $.get कॉलबैक (.always()) पहले कहा जा रहा है जीईटी अनुरोध वास्तव में खत्म होता है। कम से कम, ऐसा लगता है। वीडियो एम्बेड कोड की एक सूची के माध्यम से लूप:

कोड

var apiRequest = 'some/url/'; 

// fetch list of video embed codes 
$.get(apiRequest, function(embed_codes) { 

    // added this per Explosion Pills' answer 
    var jqxhrs = []; 

    // for each embed code, get video details (name, duration, etc.) 
    for (var i = 0; i < embed_codes.length; i++) { 
     var videoDetailsRequest = '/v2/assets/' + embed_codes[i]; 
     //..declare vars.. 

     // fetch video details 
     var jqxhr = $.get(videoDetailsRequest, function(video) { 
      // build playlist entry for each video 
      playlistItem = '<li><h3>' + video.name + '</h3><p>' + video.description + '</p></li>'; 

      // create object of video HTML, with key = "video name" for sorting later 
      videoArray[video.name] = playlistItem; 
     }, 'jsonp') 

     // added this per Explosion Pills' answer 
     jqxhrs.push(jqxhr); 
    } 

    // updated from jqxhr.always(function() { 
    $.when(jqxhrs).always(function() { 
     // create array of keys 
     for (k in videoArray) { 
      if (videoArray.hasOwnProperty(k)) { keys.push(k); } 
     } 

     // append alphabetized list of videos to the page... 
    }); 
}, 'jsonp'); 

क्या कोड

अनिवार्य रूप से करता है, कोड से करता है। for लूप के प्रत्येक पुनरावृत्ति के लिए, प्रत्येक वीडियो के बारे में विवरण प्राप्त करें और उन विवरणों को एक बहुआयामी सरणी में धक्का दें। एक बार सभी वीडियो लाने के बाद, .always() कॉलबैक पर कॉल करें, जो वीडियो को वर्णमाला प्लेलिस्ट में टाइप करता है और पृष्ठ पर जोड़ता है।

समस्या

.always() कॉलबैक से पहले सभी वीडियो को लाए जाने के लिए किया गया है कभी कभी कहा जाता हो जाता है। प्लेलिस्ट में 9 वीडियो हैं, लेकिन कॉलबैक को निकालने से पहले कभी-कभी केवल 6 या 7 लौटा दिए जाते हैं, जिसका अर्थ है कि मेरी प्लेलिस्ट थोड़ी कम है। मैंने चेतावनी() कुंजी की संख्या और कंसोल का उपयोग करके इसका परीक्षण किया है। मैंने जो देखा है वह है कि 6-7 वीडियो वापस आएंगे, फिरalert() कॉलबैक आग में, फिर शेष वीडियो लौटाए गए हैं।

मेरे सवाल:

हो रहा क्यों है? मैंने सोचा कि .always() कॉलबैक के बाद निकाल दिया गया AJAX अनुरोध पूरा हो गया था। इसका मतलब यह नहीं है कि सभी वीडियो से पहले कॉलबैक निकाल दिया जाना चाहिए? मुझे संदेह है कि इसे AJAX में "ए" के साथ करना है, लेकिन मैंने सोचा कि always() कॉलबैक का उद्देश्य इस के लिए जिम्मेदार था। मुझे समझने में मदद करने के लिए कुछ भी बहुत सराहना की है। धन्यवाद!

उत्तर

5

जिस तरह से आपने इसे सेट किया है, कॉलबैक जैसे लूप पूर्ण होने पर AJAX अनुरोध के रूप में जल्द ही आग लग जाएगा। यह दूसरों के संबंध में आदेश से बाहर हो सकता है। मैं यह नहीं बता सकता कि क्या आप इसे आग लगाना चाहते हैं जब लूप में सभी अनुरोध पूरा हो गए हैं या जब बाहरी अनुरोध पूरा हो गया है।

बाहरी अनुरोध के लिए, यह आसान है। बस .always (या .done पर कॉल करें, मुझे विश्वास है कि वे वही हैं और बाद वाले को प्राथमिकता दी जाती है)।

आप इसे जब अन्य सभी ajax अनुरोध पूरा कर रहे हैं, तो आप $.when जो जांचने पर सभी टाल वस्तुओं पूरा कर रहे हैं का उपयोग कर सकते, को पूरा करना चाहते हैं:

var jqxhrs = []; 
    ...for loop... 
    var jqxhr = $.get(videoDetailsRequest 
    ... 
    }, 'jsonp'); 
    jqxhrs.push(jqxhr); 
... 
$.when.apply(undefined, jqxhrs).always(function() { /* your intended callback */ 

वैकल्पिक रूप से, आप उपयोग कर सकते हैं .pipe:

//Create initial deferred object 
var jqxhr = $.Deferred(); 
    ...for loop... 
    jqxhr = jqxhr.pipe($.get(... 
jqxhr.always(function() { /* callback */ 
+0

आपके उत्तर के लिए धन्यवाद! मेरे पास .pipe() लेकिन '$ के साथ भाग्य नहीं था।कब() '_almost_ है। जब मैं कंसोल लॉग देखता हूं, तो कॉलबैक के अंदर 'videoArray' पहले दिखाई देता है, पहले ही सॉर्ट किया गया है, _then_ कंसोल' प्रत्येक 'लूप में प्रत्येक व्यक्तिगत वीडियो लॉग करता है। Whaaat? किसी भी कारण से, इस मार्ग पर कॉलबैक में 'लूप' को निष्पादित करने से रोकता है, इसलिए मुझे कभी भी 'कुंजी' सरणी नहीं मिलती, जिसका अर्थ है कि मैं अपनी प्लेलिस्ट नहीं बना सकता। कोई विचार क्यों है? मैंने प्लेलिस्ट बनाने वाले कोड को शामिल करने के लिए अपना उत्तर अपडेट किया। –

+1

@Ryan यह संभव है कि '$ .when' को तर्क के रूप में सरणी पसंद नहीं है, इसलिए '$ .when.apply (अपरिभाषित, jqxhrs)' का प्रयास करें (यह' $ .when' विधि को कॉल करेगा, लेकिन गुजरने के बजाय एक सरणी यह ​​काम करेगी जैसे कि यह '$ .when (jqxhrs [0], jqxhrs [1] ...)' –

+0

यह काम करता है! धन्यवाद! बस मुझे समझ में आता है, क्या मुझे यह सब अतिरिक्त करना है सामान क्योंकि मैं एक 'फॉर' लूप के अंदर एक एजेक्स कॉल कर रहा हूं (जो कि खुद को '$ .get() 'अनुरोध के अंदर है)? सामान्य परिस्थितियों में' .always() 'कॉलबैक को AJAX अनुरोध पूरा होने के बाद निकाल दिया जाना चाहिए , है ना? –