[jquery] jQuery가 Ajax 호출이 종료되기 전에 대기하도록하려면 어떻게해야합니까?

로그인이 필요한 서버 측 기능이 있습니다. 사용자가 로그인 한 경우이 기능은 성공시 1을 반환합니다. 그렇지 않으면 함수는 로그인 페이지를 반환합니다.

Ajax와 jQuery를 사용하여 함수를 호출하고 싶습니다. 내가하는 일은 클릭 기능이 적용된 일반 링크로 요청을 제출하는 것입니다. 사용자가 로그인하지 않았거나 함수가 실패하면 Ajax 호출이 true를 반환하여 href가 트리거되기를 원합니다.

그러나 다음 코드를 사용하면 Ajax 호출이 완료되기 전에 함수가 종료됩니다.

사용자를 로그인 페이지로 정상적으로 리디렉션하려면 어떻게해야합니까?

$(".my_link").click(
    function(){
    $.ajax({
        url: $(this).attr('href'),
        type: 'GET',
        cache: false,
        timeout: 30000,
        error: function(){
            return true;
        },
        success: function(msg){ 
            if (parseFloat(msg)){
                return false;
            } else {
                return true;
            }
        }
    });
});



답변

$.ajax()함수가 즉시 리턴 되지 않게 하려면 async옵션을 false다음으로 설정하십시오 .

$(".my_link").click(
    function(){
    $.ajax({
        url: $(this).attr('href'),
        type: 'GET',
        async: false,
        cache: false,
        timeout: 30000,
        error: function(){
            return true;
        },
        success: function(msg){ 
            if (parseFloat(msg)){
                return false;
            } else {
                return true;
            }
        }
    });
});

그러나 이것이 AJAX의 요점과 반대되는 점에 주목할 것입니다. 또한 errorsuccess함수 에서 응답을 처리해야합니다 . 이러한 함수는 서버에서 응답을 수신 한 경우에만 호출됩니다.


답변

내가 사용하고 있지 않다 $.ajax$.post하고 $.get내가 응답을 기다릴 필요가 그렇다면, 기능을, 내가 이것을 사용 :

$.ajaxSetup({async: false});
$.get("...");


답변

기본 XMLHttpRequest 객체 (요청을 위해 jQuery에서 사용)는 비동기 속성을 지원합니다. false로 설정하십시오 . 처럼

async: false


답변

일반적으로 잘못된 디자인 인 async를 false로 설정하는 대신 작업이 보류중인 동안 UI를 차단하는 것이 좋습니다.

이것은 다음과 같이 jQuery 약속으로 훌륭하게 달성 할 수 있습니다.

// same as $.ajax but settings can have a maskUI property
// if settings.maskUI==true, the UI will be blocked while ajax in progress
// if settings.maskUI is other than true, it's value will be used as the color value while bloking (i.e settings.maskUI='rgba(176,176,176,0.7)'
// in addition an hourglass is displayed while ajax in progress
function ajaxMaskUI(settings) {
    function maskPageOn(color) { // color can be ie. 'rgba(176,176,176,0.7)' or 'transparent'
        var div = $('#maskPageDiv');
        if (div.length === 0) {
            $(document.body).append('<div id="maskPageDiv" style="position:fixed;width:100%;height:100%;left:0;top:0;display:none"></div>'); // create it
            div = $('#maskPageDiv');
        }
        if (div.length !== 0) {
            div[0].style.zIndex = 2147483647;
            div[0].style.backgroundColor=color;
            div[0].style.display = 'inline';
        }
    }
    function maskPageOff() {
        var div = $('#maskPageDiv');
        if (div.length !== 0) {
            div[0].style.display = 'none';
            div[0].style.zIndex = 'auto';
        }
    }
    function hourglassOn() {
        if ($('style:contains("html.hourGlass")').length < 1) $('<style>').text('html.hourGlass, html.hourGlass * { cursor: wait !important; }').appendTo('head');
        $('html').addClass('hourGlass');
    }
    function hourglassOff() {
        $('html').removeClass('hourGlass');
    }

    if (settings.maskUI===true) settings.maskUI='transparent';

    if (!!settings.maskUI) {
        maskPageOn(settings.maskUI);
        hourglassOn();
    }

    var dfd = new $.Deferred();
    $.ajax(settings)
        .fail(function(jqXHR, textStatus, errorThrown) {
            if (!!settings.maskUI) {
                maskPageOff();
                hourglassOff();
            }
            dfd.reject(jqXHR, textStatus, errorThrown);
        }).done(function(data, textStatus, jqXHR) {
            if (!!settings.maskUI) {
                maskPageOff();
                hourglassOff();
            }
            dfd.resolve(data, textStatus, jqXHR);
        });

    return dfd.promise();
}

이것으로 당신은 지금 할 수 있습니다 :

ajaxMaskUI({
    url: url,
    maskUI: true // or try for example 'rgba(176,176,176,0.7)'
}).fail(function (jqXHR, textStatus, errorThrown) {
    console.log('error ' + textStatus);
}).done(function (data, textStatus, jqXHR) {
    console.log('success ' + JSON.stringify(data));
});

그리고 ajax 명령이 반환 될 때까지 UI가 차단됩니다.

jsfiddle 참조


답변

나는 일을 당신이 당신의 코드를하면 쉬울 것이라고 생각 success반환하는 대신 해당 페이지를로드하는 기능을 true하거나 false.

예를 들어 돌아 오는 대신 true다음을 수행 할 수 있습니다.

window.location="appropriate page";

그렇게하면 성공 함수가 호출 될 때 페이지가 리디렉션됩니다.


답변

현대 JS에서는 다음 과 같이 간단히 async/ 를 사용할 수 있습니다 await.

  async function upload() {
    return new Promise((resolve, reject) => {
        $.ajax({
            url: $(this).attr('href'),
            type: 'GET',
            timeout: 30000,
            success: (response) => {
                resolve(response);
            },
            error: (response) => {
                reject(response);
            }
        })
    })
}

그런 다음 다음 async과 같은 함수로 호출하십시오 .

let response = await upload();


답변

여기에 언급되어 있지 않으므로 jQuery when 문 이이 목적에 매우 유용 할 수 있다고 생각했습니다.

그들의 예는 다음과 같습니다 :

$.when( $.ajax( "test.aspx" ) ).then(function( data, textStatus, jqXHR ) {
  alert( jqXHR.status ); // Alerts 200
});

“다음”부분은 “언제”부분이 완료 될 때까지 실행되지 않습니다.