2011-08-08 9 views
13

मैं सोच रहा हूं कि एन के समूह में AJAX कॉल कैसे करें।मैं jQuery में AJAX अनुरोधों के बैच कैसे बना सकता हूं?

यहाँ मेरी उपयोग मामला है:

मैं एक मेज है कि उपयोग डेटा प्रदर्शित होती है। आप प्रत्येक पंक्ति में ड्रिल कर सकते हैं, और यदि प्रत्येक पंक्ति में एक सामान्य विशेषता है तो आप गहराई से ड्रिल कर सकते हैं, आप एक साथ में उन सभी में ड्रिल करना चुन सकते हैं। प्रत्येक पंक्ति के लिए, डेटा को तालिका में जोड़ने के लिए एक AJAX कॉल किया जाता है।

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

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

+1

तो अपनी खुद की कतार प्रबंधक :) बनाने –

+0

इस उत्तर आम तौर पर http://stackoverflow.com/questions/42425885/trying-to-make-2-ajax में मदद करता है -कॉल-थ्रू-जेक्वायरी-एंड-फिर-प्रीपेन्डिंग-द-डेटा-ले लिया गया/42426722 # 42426722 –

उत्तर

16

आप पर एक नज़र ले जा सकते हैं:

एक और तरीका है अपने जावास्क्रिप्ट में प्रत्यावर्तन का उपयोग करने के लिए इतना है कि कॉल अभी भी अतुल्यकालिक हैं, लेकिन ajax कॉल अभी भी निम्नलिखित की तरह प्रत्येक पंक्ति की सफलता घटना के लिए इंतजार कर रहा है है jQuery.when का उपयोग करके, जो आपको सभी अनुरोध पूरा होने पर कॉलबैक फ़ंक्शंस निष्पादित करने की अनुमति देता है।

$.when($.ajax("request1"), $.ajax("request2"), $.ajax("request3")) 
.done(function(data1, data2, data3){ 
     // Do something with the data 
}); 

या

$.when($.ajax("request1"), $.ajax("request2"), $.ajax("request3")) 
.then(successCallback, errorHandler); 

अधिक जानकारी के लिए निम्न post देखें।

इसके अलावा, मुझे यकीन नहीं है कि प्लगइन का उपयोग करने की आपकी आशंका इस तथ्य से प्रभावित होनी चाहिए कि आप एक कार्य वातावरण में हैं, खासकर यदि यह आपके काम को सरल बनाता है। इसलिए अधिक उत्पादक होने की इजाजत दी गई है। माना जाता है कि आपको अपने प्लगइन सावधानीपूर्वक चुनना है, क्योंकि गुणवत्ता और दीर्घकालिक रखरखाव एक मुद्दा हो सकता है।

+1

jQuery [Deferred ऑब्जेक्ट] (http://api.jquery.com/category/deferred-object/) असीमित अनुरोधों को संभालने के दौरान निश्चित रूप से जाने का तरीका है। $ .jhen और $ .done का उपयोग करते समय $ .ajax वादे ऑब्जेक्ट्स और सेटटाइमआउट द्वारा उत्पन्न कोड ने मेरा कोड क्लीनर और अधिक पठनीय बनाया है। अच्छा निर्णय। – stinkycheeseman

+0

हां $ .when() समझते हैं, लेकिन यह मेरे मामले के लिए उपयोग करने के लिए cumbersone दिखता है जो 5K xhr2 प्रश्न है, इसे 50 के बैच भेजे गए हैं। (क्रोम एसपीडीवाई सर्वर के साथ मेमोरी गलती फेंकता है), क्रोमियम लोग अंततः ठीक हो जाएंगे, लेकिन मुझे थ्रॉटलिंग चाहिए अभी व। मुझे लगता है कि मैं नीचे रिकर्सन सुझाव का प्रयास कर सकता हूं। क्या यह सही लगता है? –

7

jQuery का उपयोग करते हुए अजाक्स कॉल आमतौर पर असीमित होते हैं। इसलिए, यदि आपके पास 50 पंक्तियां हैं, तो jQuery सभी 50 अनुरोधों को अतुल्य रूप से भेज देगा - जब आप सर्वर से प्रतिक्रिया प्राप्त करते हैं तो आपको प्रसंस्करण के अनुक्रम को नियंत्रित नहीं किया जाता है।

आप $.ajax फोन पर async: false उपयोग कर सकते हैं ऐसी है कि केवल एक अनुरोध अपनी पंक्तियों के माध्यम से लूप के रूप में सर्वर के लिए भेजा जाता है:

$.ajax({ 
    url: location, 
    data: params, 
    async: false, 
    success: function(msg) { // do something} 
}); 

इस दृष्टिकोण (async: false) के साथ मुद्दा यह है कि उपयोगकर्ता एक अनुभव हो सकता है है "फ्रीज" या उत्तरदायी पृष्ठ।

var maxRows = 50; 

function myFunc(index) { 
    $.ajax({ 
     url: location, 
     data: params, 
     async: true, 
     success: function(msg) { 
      if (index < maxRows) { 
       // do something 
      } 
      else { 
       return; //index equals maxRows--stop the recursion 
      } 
      index++; 
      myFunc(index); //call the function again 
     } 
    }); 

    $(document).ready(function() { 
     myFunc(0);  
    }); 
} 
+0

मुझे 5 के xhr2 प्रश्नों को करने की ज़रूरत है, इसे 50 के बैच भेजे गए हैं। (क्रोम एसपीडीवाई सर्वर के साथ मेमोरी गलती फेंकता है) क्रोमियम लोग अंततः ठीक हो जाएंगे, लेकिन मुझे अब थ्रॉटलिंग की आवश्यकता है। मुझे लगता है कि आपके रिकर्सन दृष्टिकोण का वादा किया गया है। –

3

मैं ईसीटीओ से सहमत हूं: यदि आप किसी अन्य को एकीकृत नहीं कर सकते हैं तो अपना स्वयं का संदेश प्रबंधक बनाएं। यहाँ एक छोटे से एक पर मेरी दरार है:

var AjaxQueue = function(max) { 
    this.max = max; 
    this.requests = []; 
    this.current = 0; 
} 

AjaxQueue.prototype.ajax = function(opts) { 
    var queue = this; 
    opts.complete = function(jqXHR, textStatus) { 
    queue.current -= 1; 
    queue.send(); 
    }; 
    this.requests.push(opts); 
    this.send(); 
} 

AjaxQueue.prototype.send = function(opts) { 
    while (this.current < this.max && this.requests.length > 0) { 
    $.ajax(this.requests.unshift()); 
    this.current += 1; 
    } 
} 

मैं अभी तक यह उपयोग करने की कोशिश नहीं की है, इसलिए वहाँ कीड़े होने के लिए बाध्य कर रहे हैं। यह भी मानता है कि आप complete विकल्प का उपयोग नहीं कर रहे हैं। यह सिर्फ इसे ओवरराइड करता है। यदि आप हैं तो आप इसकी जांच कर सकते हैं और सुनिश्चित कर सकते हैं कि पिछले पूर्ण कार्य अभी भी कॉल हो जाएं।

+0

आह महान यह सही है। मैं इसके साथ खेलूँगा और देख सकता हूं कि मैं क्या कर सकता हूं। मेरी एकमात्र चिंता यह है कि क्या इस.current में दौड़ की स्थिति की संभावना है? मुझे पता है कि यह दुर्लभ है कि एक ही समय में 2 AJAX कॉल पूर्ण हो गए हैं, तो क्या इसके बारे में सोचने लायक है? – stinkycheeseman

+2

नहीं। ब्राउज़र सुनिश्चित करता है कि दो उपयोगकर्ता-परिभाषित फ़ंक्शंस एक ही समय में नहीं चल सकते हैं। यही कारण है कि एक अनंत चल रहा है जबकि लूप वेब पेज के साथ बातचीत को लॉक करेगा। यह चीजों को आसान बनाता है। –

+0

उपयोग उदाहरण का कोई मौका? – PlanetWilson

0

कॉल के रिकर्सिव बैचिंग मेरे लिए काम करता है। लेकिन चूंकि मुझे XHR2 ब्लॉब्स के 4K मिल रहे हैं और इंडेक्सड डीबी (पाउचडीबी) में प्रत्येक को सहेज रहे हैं। मेरे पास XHR2 और आईडीबी दोनों के लिए धागे हैं।तो मैं थोड़ा और अधिक परिष्कृत होना ही था:

 for (var i in info.LayerInfo) { 
     var imageType = (info.LayerInfo[i].Class == "BASE") ? "jpg" : "png"; 
     info.LayerInfo[i].SaveCount = 0; 
     getLayer(0, info, info.LayerInfo[i], info.LayerInfo[i].Path, imageType); 
    } 
} 

function getLayer(index, info, layer, base, imageType) { 
    if (layer.Files.length == 0) { 
     console.log("Thread done: " + index + " SaveCount: " + layer.SaveCount); 
     return; 
    } 
    var val = layer.Files.shift(); 
    var path = base + "/" + val.id + "." + imageType; 
    $xhr.ajax({ 
     url: path, 
     dataType: "blob", 
     success: function (data) { 
      console.log("fetched: ", layer.Type + "-" + val.id); 
      saveBlob(data, val.size, val.id, layer.Type, index, info, layer, base, imageType); 
      if (index < maxThreads - 1) { 
       getLayer(++index, info, layer, base, imageType); 
      } else { 
       return; 
      } 
     } 
    }); 
} 

function saveBlob(blob, length, id, layerID, index, info, layer, base, imageType) { 
    if (blob.size != length) { 
     console.error("Blob Length found: ", blob.size, " expected: ", length); 
    } 
    var blobID = layerID + "-" + id; 
    var type = blob.type; 
    DB.putAttachment(blobID + "/pic", blob, type, function (err, response) { 
     if (err) { 
      console.error("Could store blob: error: " + err.error + " reason: " + err.reason + " status: " + err.status); 
     } else { 
      console.log("saved: ", response.id + " rev: " + response.rev); 
      layer.SaveCount++; 
      getLayer(index, info, layer, base, imageType); 
     } 
    }); 
} 
संबंधित मुद्दे