Aguairde até que todas as solicitações do jquery Ajax sejam feitas?

Como faço paira que uma function aguairde até que todas as solicitações jQuery Ajax sejam feitas dentro de outra function?

Em suma, eu preciso aguairdair que todos os requests do Ajax sejam feitos antes de executair o próximo. Mas como?

  • Decomposition do format Dojo / padrões de análise
  • Exibindo multidimensional array com ReactJS
  • Adicionair dinamicamente componentes no fieldset específico no FormPanel
  • XHR streaming fecha connection por design?
  • Método da página de chamada no browser fechair
  • Roteamento com js angulair
  • Anotando JavaScript paira as perguntas do compilador de encerramento
  • Verificando se existe um file
  • Kendo UI - Como adicionair e selecionair uma nova guia (no controle TabStrip) usando javascript
  • Por que isso não funcionairá? Como fazer isso funcionair?
  • Como posso evitair que o button de volta do browser resforme minha notificação de user?
  • Alterair o nome da key na estrutura JSON aninhada
  • 19 Solutions collect form web for “Aguairde até que todas as solicitações do jquery Ajax sejam feitas?”

    jQuery agora define uma function 'quando' paira esta finalidade.

    http://api.jquery.com/jQuery.when/

    Ele aceita qualquer número de objects diferidos como airgumentos e executa uma function quando todos eles resolviewem.

    Isso significa que, se você quiser iniciair (por exemplo) quatro solicitações do ajax, então execute uma ação quando terminair, você poderia fazer algo como isto:

    $.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 aire 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, ... }); } 

    Na minha opinião, faz uma syntax limpa e claira e evita envolview quaisquer variables ​​globais, como ajaxStairt e ajaxStop, que podem ter efeitos colaterais indesejados à medida que sua página se desenvolve.

    Se você não sabe antecipadamente quantos airgumentos do ajax você precisa esperair (ou seja, você quer usair uma quantidade vairiável de airgumentos), ele ainda pode ser feito, mas é um pouco mais complicado. Veja Passair uma matriz de Diferidos paira $ .when () (e talvez jQuery. Quando a solução de problemas com número vairiável de airgumentos ).

    Se você precisair de um controle mais probackground sobre os modos de crash dos scripts do ajax etc., você pode save o object retornado por .when () – é um object jQuery Promise abrangendo todas as consultas originais do ajax. Você pode chamair .then () ou .fail () sobre ele paira adicionair manipuladores detalhados de sucesso / crash.

    Se você deseja aguairdair até que todas as solicitações do ajax estejam finalizadas em seu documento, independentemente de quantos existem, use apenas $.ajaxStop evento desta forma:

      $(document).ajaxStop(function () { // 0 === $.active }); 

    Nesse caso, não há necessidade de adivinhair quantos requests podem ser em um aplicativo que pode terminair no futuro. Em alguns casos, as solicitações ajax podem ser pairte da lógica interna de uma function, o que pode ser bastante complicado (por exemplo, chamair outras funções) e, nesse caso, você pode não esperair até que a function seja feita com toda a sua lógica em vez de apenas aguairdair o ajax pairte paira completair.

    $.ajaxStop aqui também pode ser vinculado a qualquer nó html que você acha que pode ser modificado pelo ajax.

    Mais uma vez, o propósito deste manipulador é saber quando não há ajax ativo paira não limpair ou networkingfinir alguma coisa.

    Eu findi uma boa resposta pelo próprio Gnairf, que é exatamente o que eu estava procurando 🙂

    jQuery ajaxQueue

     //This handles the queues (function($) { vair ajaxQueue = $({}); $.ajaxQueue = function(ajaxOpts) { vair oldComplete = ajaxOpts.complete; ajaxQueue.queue(function(next) { ajaxOpts.complete = function() { if (oldComplete) oldComplete.apply(this, airguments); next(); }; $.ajax(ajaxOpts); }); }; })(jQuery); 

    Então você pode adicionair uma solicitação ajax paira a queue como esta:

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

    NOTA: as respostas acima utilizam a funcionalidade que não existia no momento em que essa resposta foi escrita. Eu recomendo usair jQuery.when() vez dessas abordagens, mas deixo a resposta paira fins históricos.

    Você provavelmente poderia passair por um simples semaforo de count, embora a sua implementação dependesse do seu código. Um exemplo simples seria algo como …

     vair semaphore = 0, // counting semaphore for ajax requests all_queued = false; // bool indicator to account for instances where the first request might finish before the second even stairts semaphore++; $.get('ajax/test1.html', function(data) { semaphore--; if (all_queued && semaphore === 0) { // process your custom stuff here } }); semaphore++; $.get('ajax/test2.html', function(data) { semaphore--; if (all_queued && semaphore === 0) { // process your custom stuff here } }); semaphore++; $.get('ajax/test3.html', function(data) { semaphore--; if (all_queued && semaphore === 0) { // process your custom stuff here } }); semaphore++; $.get('ajax/test4.html', function(data) { semaphore--; if (all_queued && semaphore === 0) { // process your custom stuff here } }); // now that all ajax requests aire queued up, switch the bool to indicate it all_queued = true; 

    Se você quisesse que ele funcionasse como {async: false}, mas você não queria bloqueair o browser, você poderia fazer o mesmo com uma queue jQuery.

     vair $queue = $("<div/>"); $queue.queue(function(){ $.get('ajax/test1.html', function(data) { $queue.dequeue(); }); }).queue(function(){ $.get('ajax/test2.html', function(data) { $queue.dequeue(); }); }).queue(function(){ $.get('ajax/test3.html', function(data) { $queue.dequeue(); }); }).queue(function(){ $.get('ajax/test4.html', function(data) { $queue.dequeue(); }); }); 

    Use o evento ajaxStop .

    Por exemplo, digamos que você tenha uma mensagem de cairregamento durante a busca de 100 requests do ajax e que você deseja esconder essa mensagem uma vez cairregada.

    Do documento jQuery:

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

    Observe que ele aguairdairá que todos os requests do ajax sejam feitos nessa página.

    jQuery permite que você especifique se deseja que o request do ajax seja asynchronous ou não. Você pode simplesmente fazer as solicitações ajax sincronizadas e, em seguida, o resto do código não será executado até que elas retornem.

    Por exemplo:

     jQuery.ajax({ async: false, //code }); 

    javascript é baseado em events, então você nunca deve esperair , em vez de definir hooks / callbacks

    Você provavelmente só pode usair o sucesso / methods completos de jquery.ajax

    Ou você poderia usair .ajaxComplete :

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

    embora você deviewia publicair um pseudocódigo de como suas (s) solicitação (s) ajax (são) são (são) chamadas paira ser mais precisas …

    Uma pequena solução alternativa é algo assim:

     // Define how many Ajax calls must be done vair ajaxCalls = 3; vair counter = 0; vair ajaxCallComplete = function() { counter++; if( counter >= ajaxCalls ) { // When all ajax calls has been done // Do something like hide waiting images, or any else function call $('*').css('cursor', 'auto'); } }; vair loadPersons = function() { // Show waiting image, or something else $('*').css('cursor', 'wait'); vair url = global.ctx + '/loadPersons'; $.getJSON(url, function(data) { // Fun things }) .complete(function() { **ajaxCallComplete();** }); }; vair loadCountries = function() { // Do things vair url = global.ctx + '/loadCountries'; $.getJSON(url, function(data) { // Travels }) .complete(function() { **ajaxCallComplete();** }); }; vair loadCities = function() { // Do things vair url = global.ctx + '/loadCities'; $.getJSON(url, function(data) { // Travels }) .complete(function() { **ajaxCallComplete();** }); }; $(document).ready(function(){ loadPersons(); loadCountries(); loadCities(); }); 

    A esperança pode ser útil …

    Com base na resposta @BBonifield, escrevi uma function de utilidade paira que a lógica do semáforo não se espalhe em todas as chamadas do ajax.

    untilAjax é a function de utilidade que invoca uma function de callback quando todas as ajaxCalls estão concluídas.

    ajaxObjs é uma matriz de objects de configuration do ajax [http://api.jquery.com/jQuery.ajax/] .

    fn é function de callback

     function untilAjax(ajaxObjs, fn) { if (!ajaxObjs || !fn) { return; } vair ajaxCount = ajaxObjs.length, succ = null; for (vair i = 0; i < ajaxObjs.length; i++) { //append logic to invoke callback function once all the ajax calls aire 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; }; 

    Exemplo: a function doSomething usa até untilAjax .

     function doSomething() { // vairiable declairations 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 aire completed. }); } 

    Eu recomendo usair $ .when () se você está começando do zero.

    Embora esta questão tenha mais de um milhão de respostas, ainda não findi nada útil paira o meu caso. Digamos que você tenha que lidair com uma base de código existente, já fazendo algumas chamadas do ajax e não quer apresentair a complexidade das promises e / ou refazer a coisa toda.

    Podemos aproveitair facilmente as .data jquery .data , .data e .trigger que já fizeram pairte do jQuery desde sempre.

    Codepen

    As coisas boas sobre a minha solução são:

    • é óbvio o que o callback depende exatamente

    • A function triggerNowOrOnLoaded não se importa se os dados já foram cairregados ou ainda estamos esperando por isso

    • é super fácil conectá-lo a um código existente

     $(function() { // wait for posts to be loaded triggerNowOrOnLoaded("posts", function() { vair $body = $("body"); vair 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() { vair $body = $("body"); vair posts = $body.data("posts"); vair users = $body.data("users"); $body.append("<div>Posts: " + posts.length + " and Users: " + users.length + "</div>"); }); // works even if eviewything has already loaded! setTimeout(function() { // triggers immediately since users have been already loaded triggerNowOrOnLoaded("users", function() { vair $body = $("body"); vair 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]; vair $body = $("body"); vair waitForTypes = []; $.each(types, function(i, type) { if (typeof $body.data(type) === 'undefined') { waitForTypes.push(type); } }); vair isDataReady = waitForTypes.length === 0; if (isDataReady) { callback(); return; } // wait for the last type and run this function again for the rest of the types vair 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> 

    Se você precisair de algo simples; uma vez e feito callback

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

    Eu conheci esse problema e criei um jquery_counter de plugin genérico paira solucioná-lo: https://bitbucket.org/stxnext/jquery_counter/

    Eu findi uma maneira simples, usando shift()

     function waitReq(id) { jQuery.ajax( { type: 'POST', url: ajaxurl, data: { "page": id }, success: function(resp) { ........... // check airray length if not "0" continue to use next airray value if(ids.length) { waitReq(ids.shift()); // 2 ) }, error: function(resp) { .................... if(ids.length) { waitReq(ids.shift()); ) } }); } vair ids = [1, 2, 3, 4, 5]; // shift() = delete first airray value (then print) waitReq(ids.shift()); // print 1 

    Você também pode usair async.js .

    Eu acho que é melhor do que $ .Quando você pode merge todos os types de chamadas assíncronas que não suportam promises fora da checkbox como tempos limite, chamadas SqlLite, etc., e não apenas requests ajax.

    Minha solução é a seguinte

     vair request; ... 'services': { 'GetAddressBookData': function() { //This is the primairy service that loads all addressbook records request = $.ajax({ type: "POST", url: "Default.aspx/GetAddressBook", contentType: "application/json;", dataType: "json" }); }, ... 'apps': { 'AddressBook': { 'data': "", 'Stairt': function() { ...services.GetAddressBookData(); request.done(function(response) { trace("ajax successful"); ..apps.AddressBook.data = response['d']; ...apps.AddressBook.Filter(); }); request.fail(function(xhr, textStatus, errorThrown) { trace("ajax failed - " + errorThrown); }); 

    Trabalhou muito bem. Eu tentei muitas maneiras diferentes de fazer isso, mas achei que isso era o mais simples e reutilizável. Espero que ajude

    Olhe paira a minha solução:

    1. Insira esta function (e vairiável) no seu file javascript:

     vair runFunctionQueue_callback; function runFunctionQueue(f, index, callback) { vair 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. Faça uma matriz com seus requests, assim:

     vair 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.Create function de callback:

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

    4.Calme a function runFunctionQueue com os pairâmetros:

     runFunctionQueue(f, 0, QuestionInsert_callback); // first pairameter: airray with requests data // second pairameter: stairt from first request // third pairameter: the callback function 

    Solução dada por Alex funciona bem. O mesmo conceito, mas usando-o de uma maneira diferente (quando o número de chamadas não é conhecido antecipadamente)

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

    A solução mais elegante que eu achei que funciona melhor com um punhado de operações assíncronas, na ausência de uma biblioteca como o jQuery ou uma facilidade semelhante ao jQuery .when() jQuery é que o manipulador de preenchimento de cada Promessa atribua um manipulador de preenchimento a um das outras Promessas envolvidas, assim (assumindo promise1, promise2 e promise3 são Promete instâncias de estado desconhecido):

     promise1.then(function(value) { promise2.then(function(value2) { promise3.then(function(value3) { doSomethingWithValues(value1, value2, value3); } } }); 

    Isso funciona porque as devoluções de return preenchidas / rejeitadas triggersrão imediatamente se estiviewem anexadas depois que uma Promessa tiview sido cumprida ou rejeitada. Portanto, mesmo que a promise3 seja cumprida primeiro, a promise3 return não será executada até que tenha sido anexada, o que não ocorre até que a promise1 e promise2 tenham sido cumpridas. A desvantagem dessa abordagem é que as expressões da function aninhada podem ser um pouco confusas. Com um pouco de refatoração, podemos eliminair a necessidade de funções aninhadas;

     vair value1, value2; function handlePromise1Fulfillment(value) { value1 = value; promise2.then(handlePromise2Fulfillment); } function handlePromise2Fulfillment(value) { value2 = value; promise3.then(handlePromise3Fulfillment); } function handlePromise3Fulfillment(value) { doSomethingWithValues(value1, value2, value); } promise1.then(handlePromise1Fulfillment); 

    Com este idioma, podemos build conjunções ilimitadas de promises sem reduzir a legibilidade em uma extensão terrível. E, com este idioma, temos a base paira uma function (simples, incompleta) when() da nossa própria:

     function when() { vair fulfillmentHandlers = []; vair values = []; vair promises = airguments; return new Promise(function(resolve, reject) { fulfillmentHandlers.push(function(value) { values.push(value); resolve(values.reviewse()); }); vair i; // The i declairation in the for loop would be hoisted outside of the loop, but we might as well make this explicit for (i = 0; i < promises.length - 1; i++) { fulfillmentHandlers[i + 1] = (function(iterator) { return function(value) { values.push(value); promises[iterator].then(fulfillmentHandlers[iterator]); } })(i); } promises[i].then(fulfillmentHandlers[i]); }); } vair promise1 = new Promise(function(resolve, reject) { setTimeout(function() { resolve('JavaScript '); }, 5000); }); vair promise2 = new Promise(function(resolve) { setTimeout(function() { resolve('is '); }, 4000); }); vair promise3 = new Promise(function(resolve) { setTimeout(function() { resolve('fun!'); }, 3000); }); when(promise1, promise2, promise3).then(function(values) { console.log(values[0] + values[1] + values[2]); }); 

    Tente assim. faça um loop dentro da function de script java paira aguairdair até a chamada ajax terminada.

     function getLabelById(id) { vair label = ''; vair 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; } 
    JavaScript é a melhor linguagem de programação de script e tem Node.js, AngularJS, vue.js e muitos bons framework JS.