programing

모든 jQuery Ajax 요청이 완료될 때까지 기다리시겠습니까?

randomtip 2022. 9. 8. 21:32
반응형

모든 jQuery Ajax 요청이 완료될 때까지 기다리시겠습니까?

함수가 다른 함수 내에서 모든 jQuery Ajax 요청이 완료될 때까지 대기하려면 어떻게 해야 합니까?

즉, 모든 Ajax 요청이 완료될 때까지 기다린 후 다음 작업을 수행해야 합니다.하지만 어떻게요?

jQuery는 이 목적을 위한 함수를 정의합니다.

임의의 수의 지연 개체를 인수로 받아들이고 모든 개체가 해결되면 함수를 실행합니다.

즉, (예를 들어)4개의 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 인수의 수를 미리 알지 못하는 경우(즉, 변수 수를 사용하는 경우)는 여전히 수행할 수 있지만 조금 더 까다로울 뿐입니다."Pass in the Deferreds to $.when()" (변수 인수에 의한 트러블 슈팅의 경우 jQuery 를 참조해 주세요).

등의 가 있는 Ajax가 할 수 .when()- 원래 Ajax 쿼리를 모두 포함하는 jQuery Promise 객체입니다.전화하시면 됩니다..then() ★★★★★★★★★★★★★★★★★」.fail()자세한 성공/실패 핸들러를 추가합니다.

당신이 알고 싶다면 ajax요청은 문서에서 완료되며, 요청의 수에 관계없이 event를 다음과 같이 사용합니다.

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

개의 .이러한 .또, , 하고 있는지를 필요도 .HTTP(S)청한한다

$.ajaxStop 여기서도 어떤 것과도 결부될 수 있다HTML수정될 수 있다고 생각되는 노드입니다.



ES구문을 사용하면 이미 알고 있는 경우에 사용할 수 있습니다.ajax★★★★★★★★★★★★★★★★★★:

Promise.all([ajax1(), ajax2()]).then(() => {
  // all requests finished successfully
}).catch(() => {
  // all requests finished but one or more failed
})

은 이 두 가 모두 입니다.Promises ★★★★★★★★★★★★★★★★★」$.ajax청한한다

여기 jsFiddle 데모가 있습니다.


2 ★★★★★★★★★
비동기/대기 구문을 사용한 최신 버전:

try {
  const results = await Promise.all([ajax1(), ajax2()])
  // do other actions
} catch(ex) { }

저는 제 자신을 갈기갈기 찢어서 좋은 을 찾았습니다.그게 바로 제가 찾고 있던 것입니다:)

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);
        }
    });

메모: 위의 답변은 이 답변이 작성되었을 때 존재하지 않았던 기능을 사용합니다.를 사용하는 것을 추천합니다.jQuery.when()하지만 역사적 목적을 위해 답을 남기는 거야

-

간단한 세마포어만으로 그럭저럭 버틸 수 있을 것입니다만, 실장 방법은 코드에 따라 다릅니다.간단한 예로는...

var 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 starts

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 are queued up, switch the bool to indicate it
all_queued = true;

이 작업을 {async: false}처럼 수행하지만 브라우저를 잠그지 않으려면 jQuery 큐에서도 동일한 작업을 수행할 수 있습니다.

var $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();
    });
});

하다를 사용하세요.ajaxStop

예를 들어, 100개의 ajax 요청을 가져오는 동안 로딩 ... 메시지가 발생했으며 로딩된 메시지를 숨기려고 한다고 가정합니다.

jQuery 문서에서:

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

이 페이지에서 실행되는 모든 ajax 요청을 대기합니다.

간단한 회피책은 다음과 같습니다.

// Define how many Ajax calls must be done
var ajaxCalls = 3;
var counter = 0;
var 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');
    }
};

var loadPersons = function() {
        // Show waiting image, or something else
    $('*').css('cursor', 'wait');

    var url = global.ctx + '/loadPersons';
    $.getJSON(url, function(data) {
            // Fun things
    })
    .complete(function() { **ajaxCallComplete();** });
};

var loadCountries = function() {
    // Do things
    var url = global.ctx + '/loadCountries';
    $.getJSON(url, function(data) {
            // Travels
    })
    .complete(function() { **ajaxCallComplete();** });
};

var loadCities = function() {
    // Do things
    var url = global.ctx + '/loadCities';
    $.getJSON(url, function(data) {
            // Travels
    })
    .complete(function() { **ajaxCallComplete();** });
};

$(document).ready(function(){
    loadPersons();
    loadCountries();
    loadCities();
});

희망은 유용할 수 있다...

javascript는 이벤트 기반이므로 기다리지 말고 후크/콜백을 설정합니다.

jquery.ajax의 success/complete 메서드를 사용할 수 있습니다.

또는 .ajax Complete를 사용할 수 있습니다.

$('.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 요청을 호출하는 방법에 대한 유사 코드를 게시해야 합니다.

jQuery를 사용하면 Ajax 요청을 비동기화할지 여부를 지정할 수 있습니다.단순히 ajax 요청을 동기화하면 나머지 코드는 반환될 때까지 실행되지 않습니다.

예를 들어 다음과 같습니다.

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

에서는, 「 「 」를 할 수 .ajaxStop()아약스

$(document).ajaxStop(function() {
     // This function will be triggered every time any ajax request is requested and completed
});

에 는,ajax()하세요.complete()Ajax:

$.ajax({
    type: "POST",
    url: "someUrl",
    success: function(data) {
        // This function will be triggered when ajax returns a 200 status code (success)
    },
    complete: function() {
        // This function will be triggered always, when ajax request is completed, even it fails/returns other status code
    },
    error: function() {
        // This will be triggered when ajax request fail.
    }
});


단, 가지 Ajax 요청만 기다리면 될까요?멋진 javascript 약속을 사용하여 기다리고 싶은 아약스가 완료될 때까지 기다리십시오.저는 약속과 에이잭스가 어떻게 작용하는지 보여드리기 위해 간단하고 읽기 쉬운 예를 만들었습니다.
다음 예를 보세요.나는 사용했다setTimeout를 참조해 주세요.

// Note:
// resolve() is used to mark the promise as resolved
// reject() is used to mark the promise as rejected

$(document).ready(function() {
    $("button").on("click", function() {

        var ajax1 = new Promise((resolve, reject) => {
            $.ajax({
                type: "GET",
                url: "https://miro.medium.com/max/1200/0*UEtwA2ask7vQYW06.png",
                xhrFields: { responseType: 'blob'},
                success: function(data) {
                    setTimeout(function() {
                        $('#image1').attr("src", window.URL.createObjectURL(data));
                        resolve(" Promise ajax1 resolved");
                    }, 1000);
                },
                error: function() {
                    reject(" Promise ajax1 rejected");
                },
            });
        });

        var ajax2 = new Promise((resolve, reject) => {
            $.ajax({
                type: "GET",
                url: "https://cdn1.iconfinder.com/data/icons/social-media-vol-1-1/24/_github-512.png",
                xhrFields: { responseType: 'blob' },
                success: function(data) {
                    setTimeout(function() {
                         $('#image2').attr("src", window.URL.createObjectURL(data));
                         resolve(" Promise ajax2 resolved");
                    }, 1500);
                },
                error: function() {
                    reject(" Promise ajax2 rejected");
                },
            });
        });

        var ajax3 = new Promise((resolve, reject) => {
            $.ajax({
                type: "GET",
                url: "https://miro.medium.com/max/632/1*LUfpOf7teWvPdIPTBmYciA.png",
                xhrFields: { responseType: 'blob' },
                success: function(data) {
                    setTimeout(function() {
                         $('#image3').attr("src", window.URL.createObjectURL(data));
                         resolve(" Promise ajax3 resolved");
                    }, 2000);
                },
                error: function() {
                    reject(" Promise ajax3 rejected");
                },
            });
        });
        
        Promise.all([ajax1, ajax2, ajax3]).then(values => {
            console.log("We waited until ajax ended: " + values);
            console.log("My few ajax ended, lets do some things!!")
        }, reason => {
            console.log("Promises failed: " + reason);
        });
        
        // Or if you want wait for them individually do it like this
        // ajax1.then(values => {
        //    console.log("Promise 1 resolved: " + values)
        // }, reason => {
        //     console.log("Promise 1 failed: " + reason)
        // });
    });

});
img {
  max-width: 200px;
  max-height: 100px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button>Make AJAX request</button>
<div id="newContent">
    <img id="image1" src="">
    <img id="image2" src="">
    <img id="image3" src="">
</div>

간단한 콜백이 필요한 경우(한 번 완료

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

또, 비동기.js 를 사용할 수도 있습니다.

$.when은 타임아웃, SQL Lite 콜 등 즉시 사용할 수 없는 모든 종류의 비동기 콜을 병합할 수 있기 때문에 Ajax 요청뿐만 아니라 $.when보다 낫다고 생각합니다.

@BBonifield의 답변을 바탕으로 세마포 로직이 모든 Ajax 콜에 퍼지지 않도록 유틸리티 함수를 작성했습니다.

untilAjax는 모든 ajaxCalls가 완료되면 콜백 함수를 호출하는 유틸리티 함수입니다.

ajaxObjsAjax 설정 객체의 배열입니다.[http://api.jquery.com/jQuery.ajax/].

fnis 콜백 함수

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

처음부터 $.when()을 사용할 것을 강력히 권장합니다.

이 질문의 답은 백만 개가 넘지만, 저는 여전히 제 사례에 도움이 될 만한 것을 찾지 못했습니다.예를 들어, 이미 몇 가지 AJAX 콜을 실시하고 있는 기존의 코드 베이스에 대처해야 하며, 약속의 복잡함을 도입하거나 모든 것을 다시 실행하고 싶지 않다고 합시다.

jQuery를 쉽게 이용할 수 있습니다..data,.on그리고..triggerjQuery에 포함되어 있는 함수입니다.

코드펜

솔루션의 장점은 다음과 같습니다.

  • 콜백이 정확히 무엇에 의존하는지는 명백하다

  • 함수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>

모든 에이잭스 로드가 완료되면 사이즈 체크를 사용하고 있습니다.

function get_ajax(link, data, callback) {
    $.ajax({
        url: link,
        type: "GET",
        data: data,
        dataType: "json",
        success: function (data, status, jqXHR) {
            callback(jqXHR.status, data)
        },
        error: function (jqXHR, status, err) {
            callback(jqXHR.status, jqXHR);
        },
        complete: function (jqXHR, status) {
        }
    })
}

function run_list_ajax(callback){
    var size=0;
    var max= 10;
    for (let index = 0; index < max; index++) {
        var link = 'http://api.jquery.com/ajaxStop/';
        var data={i:index}
        get_ajax(link,data,function(status, data){
            console.log(index)
            if(size>max-2){
                callback('done')
            }
            size++
            
        })
    }
}

run_list_ajax(function(info){
    console.log(info)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>

알렉스의 답변을 자세히 말씀드리자면, 저는 다양한 주장과 약속에 대한 예를 들어 보겠습니다.Ajax를 통해 이미지를 로드하고 모두 로드한 후 페이지에 표시하려고 했습니다.

그러기 위해서, 다음의 방법을 사용했습니다.

let urlCreator = window.URL || window.webkitURL;

// Helper function for making ajax requests
let fetch = function(url) {
    return $.ajax({
        type: "get",
        xhrFields: {
            responseType: "blob"
        },
        url: url,
    });
};

// Map the array of urls to an array of ajax requests
let urls = ["https://placekitten.com/200/250", "https://placekitten.com/300/250"];
let files = urls.map(url => fetch(url));

// Use the spread operator to wait for all requests
$.when(...files).then(function() {
    // If we have multiple urls, then loop through
    if(urls.length > 1) {
        // Create image urls and tags for each result
        Array.from(arguments).forEach(data => {
            let imageUrl = urlCreator.createObjectURL(data[0]);
            let img = `<img src=${imageUrl}>`;
            $("#image_container").append(img);
        });
    }
    else {
        // Create image source and tag for result
        let imageUrl = urlCreator.createObjectURL(arguments[0]);
        let img = `<img src=${imageUrl}>`;
        $("#image_container").append(img);
    }
});

단일 URL 또는 여러 URL에서 작동하도록 업데이트됨: https://jsfiddle.net/euypj5w9/

간단한 방법을 찾았습니다.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

저의 해결방법은 다음과 같습니다.

var request;
...
'services': {
  'GetAddressBookData': function() {
    //This is the primary service that loads all addressbook records 
    request = $.ajax({
      type: "POST",
      url: "Default.aspx/GetAddressBook",
      contentType: "application/json;",
      dataType: "json"
    });
  },

  ...

  'apps': {
    'AddressBook': {
      'data': "",
      'Start': 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);
          });

꽤 잘 작동했어요.여러 가지 방법을 시도해 봤지만, 가장 간단하고 재사용이 가능한 방법이라는 것을 알게 되었습니다.도움이 되었으면 좋겠다

솔루션을 보세요.

1. 다음 함수(및 변수)를 javascript 파일에 삽입합니다.

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 함수를 호출합니다.

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

$.when 안 돼, 안 돼.callback(x)return xhttps://stackoverflow.com/a/13455253/10357604 에서 설명한 대로 동작했습니다.

아래 솔루션은 $를 사용하여 작동했습니다.

$.when(master.GetStateByName(stateName)).done(function(response) {
    if (response) {

    }
});

GetStateByName: function(stateName) {
    return $.ajax({
        type: 'POST',
        url: getStatesByName + '?stateName=' + stateName,
        async: false,
    });
}

이건 나한테 효과가 있어 아주 간단해

return $.ajax({
  type: 'POST',
  url: urlBaseUrl
  data: {someData:someData},
  dataType: "json",
  success: function(resultData) { 
  }
});

이 방법을 사용해 보십시오.java 스크립트 함수 내에 루프를 만들어 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;
}

언급URL : https://stackoverflow.com/questions/3709597/wait-until-all-jquery-ajax-requests-are-done

반응형