2012-01-16 15 views
8

वास्तव में सवाल यह है कि विषय उतना आसान है जितना विषय कहता है। क्या विभिन्न AJAX हैंडलरों को उच्च/निम्न प्राथमिकता देने का कोई तरीका है (जिसका मतलब है कि वे पहले आग लगेंगे)?jQuery - सेट अजाक्स हैंडलर प्राथमिकता

मेरा क्या मतलब है? खैर, मुझे काफी विशाल वेब-ऐप से निपटना होगा। अजाक्स अनुरोधों के टन विभिन्न मॉड्यूल में निकाल दिए जाते हैं। अब, मेरा लक्ष्य एक साधारण सत्र-टाइमआउट तंत्र को लागू करना है। प्रत्येक अनुरोध वर्तमान सत्र-आईडी को पैरामीटर के रूप में भेजता है, यदि सत्र-आईडी अब मान्य नहीं है, तो मेरी बैकएंड स्क्रिप्ट एक कस्टम प्रतिक्रिया-हेडर सेट (मान एक यूरी है) के साथ अनुरोध देता है।

तो मैं मूल रूप से इस

window.jQuery && jQuery(document).ajaxComplete(function(event, xhr, settings) { 
    var redirectto = xhr.getResponseHeader('new_ajax_location'); 
    if(redirectto) { 
     location.href = redirectto; 
    } 
}); 

की तरह यह करता है निश्चित रूप से एक आकर्षण की तरह काम लिए जा रहा हूँ, लेकिन मेरी समस्या यह है कि इस वैश्विक ajax घटना वास्तव में समय के निकाल दिया करने के लिए पहले 100%, की जरूरत है जो ऐसा नहीं है। उन मूल AJAX- अनुरोध हैंडलर में से कुछ गायब या अप्रत्याशित डेटा की वजह से एक त्रुटि फेंक देंगे, उस स्थिति में, वैश्विक हैंडलर कभी निष्पादित नहीं होता है।

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

+0

शायद 'ऑनस्यूप' कॉलबैक का उपयोग करके। – Stefan

+0

@Stefan: मुझे अनुरोध के लिए सभी संभावित परिणामों को पकड़ने की आवश्यकता होगी, इसलिए 'पूर्ण' बहुत बढ़िया है। लेकिन मैंने दुर्भाग्य से उसी व्यवहार के साथ मैन्युअल रूप से 'सफलता' और 'त्रुटि' सेट करने के लिए भी जांच की। – jAndy

+0

http://stackoverflow.com/questions/290254/how-to-order-events-bound-with-jquery से संबंधित है, क्योंकि AJAX ईवेंट कोर इवेंट सिस्टम का उपयोग करके कार्यान्वित किए जाते हैं। –

उत्तर

1

यदि मैं आपको सही ढंग से समझता हूं, तो आप हर जगह जेसन अनुरोधों पर अपना स्वयं का कॉलबैक जोड़ना चाहते हैं। आप AJAXPrefilter हुक का उपयोग कर सकते हैं।

$.ajaxPrefilter(function(options, originalOptions, jqXHR) { 
     options.complete = function (jqXHR2, settings) { 
      var redirectto = jqXHR2.getResponseHeader('new_ajax_location'); 
      if(redirectto) { 
       location.href = redirectto; 
      } 
     } 
    }); 

आप अनुरोध पैरा में सत्र-आईडी जोड़ने के लिए विकल्प भी बदल सकते हैं।

0

jQuery आपको .post/.ajax जैसे तरीकों को "पैच" करने की अनुमति देता है।

आप उचित विधि (पै) को पैच करने में सक्षम हो सकते हैं, इसलिए आपका विशेष AJAX ईवेंट हमेशा आपके कोड को कॉल करने के पहले ट्रिगर किया जाता है।

यह कुछ "छद्म-jQuery-कोड" है जो आपको प्रारंभ करने में मदद कर सकता है। मुझे संदेह है कि यह काम करता है, लेकिन यह मूल अवधारणा को प्रदर्शित करता है और इसे आपको शुरू करना चाहिए।

(function($){ 
    var originalPost = $.post; 
    var calledSpecialOne = false; 
    $.post = function(url, data, success, dataType) { 
     if (!calledSpecialOne) { 
      originalPost(... your special AJAX query ...).then(function() { 
      originalPost(url, data, success, dataType); 
      } 
      calledSpecialOne = true; 
     } else { 
      originalPost(url, data, success, dataType); 
     } 
    } 
})(jQuery); 

ऊपर कुछ अन्य, असंबंधित, कोड मैं परीक्षण किया है, जो अपरिभाषित/बातिल सरणियों के लिए $ .प्रत्येक() काम करता है) पर आधारित है:

(function($){ 
    var originalEach = $.each; 
    $.each = function(collection, callback) { 
     return collection? originalEach(collection, callback) : []; 
    } 
})(jQuery); 

ध्यान दें कि कई उजागर कार्यों को भी jQuery द्वारा आंतरिक रूप से बुलाया जाता है, इसलिए इस चाल का उपयोग करके बहुत सावधान रहें; आप jQuery का एक अलग हिस्सा तोड़ सकते हैं या अन्य परेशानी का कारण बन सकते हैं। AJAX फ़ंक्शंस के मामले में, आपको असीमित रिकर्सन को रोकने के लिए, केवल आंतरिक कार्य को पैच करना चाहिए। (FWIW, मुझे अब तक $ .each() पैच के लिए कोई दुष्प्रभाव नहीं मिला है)।

+0

भले ही मुझे बतख पंचिंग सिद्धांत पसंद है, मुझे यह विशेष स्थिति में पसंद नहीं है। मुझे उपलब्ध प्रत्येक AJAX दिनचर्या पैच करना होगा, या सिर्फ पैच '.ajax()', लेकिन फिर से मैं वास्तव में वास्तव में हिम्मत नहीं करता। लेकिन कॉल ऑर्डर को संशोधित करने की कोई आधिकारिक संभावना नहीं है, लेकिन मेरे पास कोई विकल्प नहीं हो सकता है। – jAndy

0

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

यह संपत्ति priority के साथ किसी ऑब्जेक्ट को स्वीकार करने के लिए jQuery के AJAX फ़ंक्शन को पैच करता है। यदि प्राथमिकता सेट नहीं है, तो इसकी प्राथमिकता 1 (सर्वोच्च प्राथमिकता 0) बन जाती है। यदि प्राथमिकता है, तो यह दो चीजों में से एक है। यदि प्राथमिकता 5 की तरह कुछ है, तो यह देखने के लिए जांच करता है कि क्या पिछली प्राथमिकता के साथ AJAX कॉल (इस मामले में 4) को कॉल किया गया था। यदि नहीं, तो यह उस प्राथमिकता के साथ AJAX कॉल की सरणी में जोड़ता है (इस मामले में 5)।अगर पिछली प्राथमिकता को बुलाया गया है, तो यह सामान्य रूप से अनुरोध को कॉल करता है। जब किसी प्राथमिकता के साथ अनुरोध कहा जाता है, तो यह अगली सर्वोच्च प्राथमिकता के साथ किसी भी आउटगोइंग अनुरोध को कॉल करता है।

दूसरे शब्दों में, यदि कोई प्राथमिकता नहीं है, तो प्राथमिकता 0 की प्रतीक्षा करता है, यदि प्राथमिकता है, तो यह कॉल करने के लिए नीचे दी गई प्राथमिकता की प्रतीक्षा करता है। आप चाहते हैं कोई प्राथमिकता के साथ कॉल तुरंत भेजा जाना है, तो टिप्पणी के साथ लाइन बाहर टिप्पणी मैं कह रख get और post के लिए default action?

(function($){ 
     var oldAjax=$.ajax; 
     var outgoing=[]; 
     var sent=[]; 
     $.ajax=function(url, settings) { 
      var pr = (typeof url==='object'?url:settings).priority; 
      pr = pr===undefined ? 1 : pr; // default action? 
      if(pr!==undefined){ 
       if(pr==0 || sent[pr-1]!==undefined){ 
        oldAjax(url,settings); 
        sent[pr]=true; 
        if(outgoing[pr]){ 
         var rq=outgoing[pr].splice(0,1)[0]; 
         $.ajax(rq[0],rq[1]); 
        } 
        if(outgoing[pr+1]){ 
         var rq=outgoing[pr+1].splice(0,1)[0]; 
         $.ajax(rq[0],rq[1]); 
        } 
       } 
       else{ 
        if(outgoing[pr]!==undefined){ 
         outgoing[pr].push([url,settings]); 
        } 
        else{ 
         outgoing[pr]=[[url,settings]]; 
        } 
       } 
      } 
      else{ 
       oldAjax(url, settings); 
      } 
     }; 
    })(jQuery); 

पैच। आपको उन अतिरिक्त तर्कों को शामिल करना होगा, या post और get अनुरोधों के साथ प्राथमिकता प्राप्त करने के लिए इसे स्वयं बदलना होगा। यह अतिरिक्त तर्क के अलावा, jQuery 1.7 से सीधे है, और दो पंक्तियों में मैंने टिप्पणियां जोड़ दी हैं।

jQuery.each([ "get", "post" ], function(i, method) { 
    jQuery[ method ] = function(url, data, callback, type, priority) { 
     // shift arguments if data argument was omitted 
     if (jQuery.isFunction(data)) { 
      priority = type; // my change 
      type = type || callback; 
      callback = data; 
      data = undefined; 
     } 

     return jQuery.ajax({ 
      type: method, 
      url: url, 
      data: data, 
      success: callback, 
      dataType: type, 
      priority: priority // my change 
     }); 
    }; 
}); 

मैं सेटअप एक उदाहरण यहाँ: http://jsfiddle.net/tk39z/

मैं वास्तव में लक्षित कर गूगल, तो आप क्रोम में नेटवर्क पैनल की जाँच अनुरोधों को देखने के लिए कर सकते हैं कुछ ajax अनुरोध किए।

0

मैंने हाल ही में उस कार्यक्षमता के समान कुछ लागू किया है जिसे मैं मानता हूं कि आप ढूंढ रहे हैं।

मैंने वैध सत्र के परीक्षण के लिए सर्वर पक्ष पर एक फ़िल्टर सेट अप किया है, और यदि नहीं, तो अधिक विशिष्ट त्रुटि विस्तार के लिए कस्टम स्थिति टेक्स्ट के साथ 401 त्रुटि लौटाएं।

मैं इन पृष्ठों पर किए गए AJAX कॉल को 'सफलता' विशेषता का उपयोग करके सामान्य सम्मेलन में लिखा गया था।

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

$(document).ajaxError(function(e, xhr) { 
    var redirectto = xhr.getResponseHeader('new_ajax_location'); 
    if(redirectto) { 
     location.href = redirectto; 
    } 
}); 
संबंधित मुद्दे