javascript - प्रतीक्षा करें जब तक कि सभी jQuery अजाक्स अनुरोध नहीं किया जाता है?




ajax (12)

@BBonifield उत्तर के आधार पर, मैंने एक उपयोगिता फ़ंक्शन लिखा ताकि सेमफोर तर्क सभी AJAX कॉल में फैला न हो।

untilAjax उपयोगिता फ़ंक्शन नहीं है जो सभी AJAXCalls पूर्ण होने पर कॉलबैक फ़ंक्शन का आह्वान करता है।

ajaxObjs AJAX सेटिंग ऑब्जेक्ट्स की एक सरणी है [http://api.jquery.com/jQuery.ajax/]

fn कॉलबैक फ़ंक्शन है

function untilAjax(ajaxObjs, fn) {
  if (!ajaxObjs || !fn) {
    return;
  }
  var ajaxCount = ajaxObjs.length,
    succ = null;

  for (var i = 0; i < ajaxObjs.length; i++) { //append logic to invoke callback function once all the ajax calls are completed, in success handler.
    succ = ajaxObjs[i]['success'];
    ajaxObjs[i]['success'] = function(data) { //modified success handler
      if (succ) {
        succ(data);
      }
      ajaxCount--;
      if (ajaxCount == 0) {
        fn(); //modify statement suitably if you want 'this' keyword to refer to another object
      }
    };
    $.ajax(ajaxObjs[i]); //make ajax call
    succ = null;
  };

उदाहरण: doSomething कार्य फ़ंक्शन untilAjax उपयोग करता है।

function doSomething() {
  // variable declarations
  untilAjax([{
    url: 'url2',
    dataType: 'json',
    success: function(data) {
      //do something with success data
    }
  }, {
    url: 'url1',
    dataType: 'json',
    success: function(data) {
      //do something with success data
    }
  }, {
    url: 'url2',
    dataType: 'json',
    success: function(response) {
      //do something with success data
    }
  }], function() {
    // logic after all the calls are completed.
  });
}

मैं एक फ़ंक्शन प्रतीक्षा कैसे करूं जब तक कि सभी jQuery अजाक्स अनुरोध किसी अन्य फ़ंक्शन के अंदर नहीं किए जाते?

संक्षेप में, मुझे अगले निष्पादित करने से पहले सभी अजाक्स अनुरोधों को पूरा करने की प्रतीक्षा करनी होगी। पर कैसे?


jQuery अब इस उद्देश्य के लिए एक समारोह को परिभाषित करता है।

यह किसी भी संख्या में विकृत वस्तुओं को तर्क के रूप में स्वीकार करता है, और जब वे सभी हल होते हैं तो एक फ़ंक्शन निष्पादित करता है।

इसका मतलब है, यदि आप चार AJAX अनुरोधों को शुरू करना चाहते हैं (उदाहरण के लिए), तो जब वे पूरा कर लें तो एक क्रिया करें, आप ऐसा कुछ कर सकते हैं:

$.when(ajax1(), ajax2(), ajax3(), ajax4()).done(function(a1, a2, a3, a4){
    // the code here will be executed when all four ajax requests resolve.
    // a1, a2, a3 and a4 are lists of length 3 containing the response text,
    // status, and jqXHR object for each of the four ajax calls respectively.
});

function ajax1() {
    // NOTE:  This function must return the value 
    //        from calling the $.ajax() method.
    return $.ajax({
        url: "someUrl",
        dataType: "json",
        data:  yourJsonData,            
        ...
    });
}

मेरी राय में, यह एक स्वच्छ और स्पष्ट वाक्यविन्यास बनाता है, और AJAXStart और AJAXStop जैसे किसी भी वैश्विक चर को शामिल करने से बचाता है, जो आपके पृष्ठ के विकास के रूप में अवांछित साइड इफेक्ट्स हो सकता है।

यदि आप पहले से नहीं जानते हैं कि आपको कितने AJAX तर्कों की प्रतीक्षा करने की आवश्यकता है (यानी आप तर्कों की एक चर संख्या का उपयोग करना चाहते हैं), यह अभी भी किया जा सकता है लेकिन यह थोड़ा सा ट्रिकियर है। Deferreds की एक सरणी में $ .when () (और शायद jQuery। जब तर्कों की चर संख्या के साथ समस्या निवारण ) में पास देखें।

अगर आपको AJAX स्क्रिप्ट इत्यादि के विफलता मोड पर गहरा नियंत्रण की आवश्यकता है, तो आप ऑब्जेक्ट को वापस सहेज सकते हैं .when() - यह एक jQuery Promise ऑब्जेक्ट है जिसमें सभी मूल AJAX प्रश्न शामिल हैं। विस्तृत सफलता / विफलता हैंडलर जोड़ने के लिए आप इसे .fail() .then() या .fail() पर कॉल कर सकते हैं।


अगर आपको कुछ सरल चाहिए; एक बार और कॉलबैक किया

        //multiple ajax calls above
        var callback = function () {
            if ($.active !== 0) {
                setTimeout(callback, '500');
                return;
            }
            //whatever you need to do here
            //...
        };
        callback();

इस तरह से प्रयास करें। AJAX कॉल समाप्त होने तक प्रतीक्षा करने के लिए जावा स्क्रिप्ट फ़ंक्शन के अंदर एक लूप बनाएं।

function getLabelById(id)
{
    var label = '';
    var done = false;
    $.ajax({
       cache: false,
       url: "YourMvcActionUrl",
       type: "GET",
       dataType: "json",
       async: false,
       error: function (result) {
         label='undefined';
         done = true;
        },
       success: function (result) {
            label = result.Message;
            done = true;
        }
     });

   //A loop to check done if ajax call is done.
   while (!done)
   {
      setTimeout(function(){ },500); // take a sleep.
   }

    return label;
}

एलेक्स द्वारा दिए गए समाधान ठीक काम करता है। वही अवधारणा है लेकिन इसका उपयोग थोड़ा अलग तरीका है (जब कॉल की संख्या अग्रिम में ज्ञात नहीं है)

http://garbageoverflow.blogspot.com/2014/02/wait-for-n-or-multiple-or-unknown.html


जावास्क्रिप्ट घटना-आधारित है, इसलिए आपको कभी भी इंतजार नहीं करना चाहिए, बल्कि हुक / कॉलबैक सेट करना चाहिए

आप शायद jquery.ajax की सफलता / पूर्ण विधियों का उपयोग कर सकते हैं

या आप .ajaxComplete उपयोग कर सकते हैं:

$('.log').ajaxComplete(function(e, xhr, settings) {
  if (settings.url == 'ajax/test.html') {
    $(this).text('Triggered ajaxComplete handler.');
    //and you can do whatever other processing here, including calling another function...
  }
});

यद्यपि आपको एक छद्म कोड पोस्ट करना चाहिए कि कैसे आपके (ओं) AJAX अनुरोध (हैं) को अधिक सटीक कहा जाता है ...


मुझे अपने स्वयं के gnarf द्वारा एक अच्छा जवाब मिला जो वास्तव में मैं देख रहा था :)

jQuery AJAXQueue

//This handles the queues    
(function($) {

  var ajaxQueue = $({});

  $.ajaxQueue = function(ajaxOpts) {

    var oldComplete = ajaxOpts.complete;

    ajaxQueue.queue(function(next) {

      ajaxOpts.complete = function() {
        if (oldComplete) oldComplete.apply(this, arguments);

        next();
      };

      $.ajax(ajaxOpts);
    });
  };

})(jQuery);

फिर आप इस तरह की कतार में AJAX अनुरोध जोड़ सकते हैं:

$.ajaxQueue({
        url: 'page.php',
        data: {id: 1},
        type: 'POST',
        success: function(data) {
            $('#status').html(data);
        }
    });

मुझे सरल तरीका मिला, यह shift() का उपयोग कर रहा है shift()

function waitReq(id)
{
  jQuery.ajax(
  {
    type: 'POST',
    url: ajaxurl,
    data:
    {
      "page": id
    },
    success: function(resp)
    {
      ...........
      // check array length if not "0" continue to use next array value
      if(ids.length)
      {
        waitReq(ids.shift()); // 2
      )
    },
    error: function(resp)
    {
      ....................
      if(ids.length)
      {
        waitReq(ids.shift());
      )
    }
  });
}

var ids = [1, 2, 3, 4, 5];    
// shift() = delete first array value (then print)
waitReq(ids.shift()); // print 1

मेरा समाधान देखें:

1. अपनी जावास्क्रिप्ट फ़ाइल में इस फ़ंक्शन (और चर) को प्रविष्ट करें:

var runFunctionQueue_callback;

function runFunctionQueue(f, index, callback) {

  var next_index = index + 1

  if (callback !== undefined) runFunctionQueue_callback = callback;

  if (f[next_index] !== undefined) {
    console.log(index + ' Next function avalaible -> ' + next_index);
    $.ajax({
      type: 'GET',
      url: f[index].file,
      data: (f[index].data),
      complete: function() {
        runFunctionQueue(f, next_index);
      }
    });
  } else {
    console.log(index + ' Last function');
    $.ajax({
      type: 'GET',
      url: f[index].file,
      data: (f[index].data),
      async: false,
      complete: runFunctionQueue_callback
    });
  }
}

2. अपने अनुरोधों के साथ एक सरणी बनाएं, इस तरह:

var f = [
           {file: 'file_path', data: {action: 'action', data: 'any_data}},
           {file: 'file_path', data: {action: 'action', data: 'any_data}},
           {file: 'file_path', data: {action: 'action', data: 'any_data}},
           {file: 'file_path', data: {action: 'action', data: 'any_data}}
        ];

3. कॉलबैक फ़ंक्शन बनाएं:

function Function_callback() {
  alert('done');
}

4. पैरामीटर के साथ रनफंक्शन क्यूयू फ़ंक्शन कॉल करें:

runFunctionQueue(f, 0, QuestionInsert_callback);
// first parameter: array with requests data
// second parameter: start from first request
// third parameter: the callback function

मैंने इस समस्या को पूरा किया है और इसे हल करने के लिए जेनेरिक प्लगइन jquery_counter बनाया है: https://bitbucket.org/stxnext/jquery_counter/


यदि आप स्क्रैच से शुरू कर रहे हैं तो मैं अत्यधिक $.when() का उपयोग करने की सलाह देता हूं।

भले ही इस प्रश्न में लाखों उत्तर हैं, फिर भी मुझे अपने मामले के लिए कुछ भी उपयोगी नहीं मिला। आइए मान लें कि आपको मौजूदा कोडबेस से निपटना है, पहले से ही कुछ AJAX कॉल कर रहे हैं और वादे की जटिलता को पेश नहीं करना चाहते हैं और / या पूरी चीज़ को फिर से शुरू करना चाहते हैं।

हम आसानी से jQuery .trigger , .trigger और .trigger फ़ंक्शंस का लाभ उठा सकते हैं जो हमेशा के लिए jQuery का हिस्सा रहा है।

Codepen

मेरे समाधान के बारे में अच्छी चीजें हैं:

  • यह स्पष्ट है कि कॉलबैक बिल्कुल किस पर निर्भर करता है

  • फ़ंक्शन triggerNowOrOnLoaded परवाह नहीं है अगर डेटा पहले ही लोड हो चुका है या हम अभी भी इसके लिए प्रतीक्षा कर रहे हैं

  • इसे मौजूदा कोड में प्लग करना बहुत आसान है

$(function() {

  // wait for posts to be loaded
  triggerNowOrOnLoaded("posts", function() {
    var $body = $("body");
    var posts = $body.data("posts");

    $body.append("<div>Posts: " + posts.length + "</div>");
  });


  // some ajax requests
  $.getJSON("https://jsonplaceholder.typicode.com/posts", function(data) {
    $("body").data("posts", data).trigger("posts");
  });

  // doesn't matter if the `triggerNowOrOnLoaded` is called after or before the actual requests 
  $.getJSON("https://jsonplaceholder.typicode.com/users", function(data) {
    $("body").data("users", data).trigger("users");
  });


  // wait for both types
  triggerNowOrOnLoaded(["posts", "users"], function() {
    var $body = $("body");
    var posts = $body.data("posts");
    var users = $body.data("users");

    $body.append("<div>Posts: " + posts.length + " and Users: " + users.length + "</div>");
  });

  // works even if everything has already loaded!
  setTimeout(function() {

    // triggers immediately since users have been already loaded
    triggerNowOrOnLoaded("users", function() {
      var $body = $("body");
      var users = $body.data("users");

      $body.append("<div>Delayed Users: " + users.length + "</div>");
    });

  }, 2000); // 2 seconds

});

// helper function
function triggerNowOrOnLoaded(types, callback) {
  types = $.isArray(types) ? types : [types];

  var $body = $("body");

  var waitForTypes = [];
  $.each(types, function(i, type) {

    if (typeof $body.data(type) === 'undefined') {
      waitForTypes.push(type);
    }
  });

  var isDataReady = waitForTypes.length === 0;
  if (isDataReady) {
    callback();
    return;
  }

  // wait for the last type and run this function again for the rest of the types
  var waitFor = waitForTypes.pop();
  $body.on(waitFor, function() {
    // remove event handler - we only want the stuff triggered once
    $body.off(waitFor);

    triggerNowOrOnLoaded(waitForTypes, callback);
  });
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<body>Hi!</body>


ajaxStop घटना का प्रयोग करें।

उदाहरण के लिए, मान लीजिए कि आपके पास लोडिंग है ... 100 AJAX अनुरोधों को प्राप्त करते समय संदेश और आप लोड होने के बाद उस संदेश को छिपाना चाहते हैं।

JQuery $.ajaxStop :

$("#loading").ajaxStop(function() {
  $(this).hide();
});

ध्यान दें कि वह उस पृष्ठ पर किए गए सभी AJAX अनुरोधों की प्रतीक्षा करेगा।






ajax