programing

jAJAX 콜의 jQuery 콜백

fastcode 2023. 3. 6. 21:33
반응형

jAJAX 콜의 jQuery 콜백

클릭 이벤트로 3개의 에이잭스 콜을 발신하고 싶다.각 Ajax 콜은 개별 동작을 수행하고 최종 콜백에 필요한 데이터를 반환합니다.콜 자체는 서로 의존하지 않고 동시에 할 수 있지만, 3가지 콜백이 모두 완료되면 최종 콜백을 하고 싶습니다.

$('#button').click(function() {
    fun1();
    fun2();
    fun3();
//now do something else when the requests have done their 'success' callbacks.
});

var fun1= (function() {
    $.ajax({/*code*/});
});
var fun2 = (function() {
    $.ajax({/*code*/});
});
var fun3 = (function() {
    $.ajax({/*code*/});
});

이에 대한 해답이 있는 것 같습니다만, 여기서 언급할 만한 것이 있습니다.이것에 의해서, 코드의 심플화가 큰폭으로 됩니다.jQuery는 v1.5에서 도입되었습니다.외관:

$.when($.ajax(...), $.ajax(...)).then(function (resp1, resp2) {
    //this callback will be fired once all ajax calls have finished.
});

여기에 언급되어 있는 것을 보지 못했어요.

다음은 콜백 오브젝트입니다.모든 것이 완료되면1개의 콜백을 기동하도록 설정하거나 각 콜백을 각각 독자적인 콜백을 확립하여 모든 콜백을 기동할 수 있습니다.

공지

jQuery 1.5+이므로 다른 답변에서 설명한 바와 같이 지연 메서드를 사용할 수 있습니다.

  $.when($.ajax(), [...]).then(function(results){},[...]);

여기서의 지연 예

jQuery < 1.5 의 경우, 또는 다음의 2 개의 버튼(양쪽 버튼을 클릭한 실행됨)을 사용하여, 불명한 시각에 Ajax 콜을 기동할 필요가 있는 경우.

[아쉬움]

콜백이 1회 완료되었을 경우:작업 예시

// initialize here
var requestCallback = new MyRequestsCompleted({
    numRequest: 3,
    singleCallback: function(){
        alert( "I'm the callback");
    }
});

//usage in request
$.ajax({
    url: '/echo/html/',
    success: function(data) {
        requestCallback.requestComplete(true);
    }
});
$.ajax({
    url: '/echo/html/',
    success: function(data) {
        requestCallback.requestComplete(true);
    }
});
$.ajax({
    url: '/echo/html/',
    success: function(data) {
        requestCallback.requestComplete(true);
    }
});

모든 작업이 완료되면 각각 자체 콜백을 갖게 됩니다.작업 예시

//initialize 
var requestCallback = new MyRequestsCompleted({
    numRequest: 3
});

//usage in request
$.ajax({
    url: '/echo/html/',
    success: function(data) {
        requestCallback.addCallbackToQueue(true, function() {
            alert('Im the first callback');
        });
    }
});
$.ajax({
    url: '/echo/html/',
    success: function(data) {
        requestCallback.addCallbackToQueue(true, function() {
            alert('Im the second callback');
        });
    }
});
$.ajax({
    url: '/echo/html/',
    success: function(data) {
        requestCallback.addCallbackToQueue(true, function() {
            alert('Im the third callback');
        });
    }
});

[코드]

var MyRequestsCompleted = (function() {
    var numRequestToComplete, requestsCompleted, callBacks, singleCallBack;

    return function(options) {
        if (!options) options = {};

        numRequestToComplete = options.numRequest || 0;
        requestsCompleted = options.requestsCompleted || 0;
        callBacks = [];
        var fireCallbacks = function() {
            alert("we're all complete");
            for (var i = 0; i < callBacks.length; i++) callBacks[i]();
        };
        if (options.singleCallback) callBacks.push(options.singleCallback);

        this.addCallbackToQueue = function(isComplete, callback) {
            if (isComplete) requestsCompleted++;
            if (callback) callBacks.push(callback);
            if (requestsCompleted == numRequestToComplete) fireCallbacks();
        };
        this.requestComplete = function(isComplete) {
            if (isComplete) requestsCompleted++;
            if (requestsCompleted == numRequestToComplete) fireCallbacks();
        };
        this.setCallback = function(callback) {
            callBacks.push(callBack);
        };
    };
})();

어떤 물건도 필요없다는 걸 스스로 깨닫지 못했죠Simple에는 정수인 변수가 있습니다.요청을 시작할 때 수를 늘립니다.하나가 완성되면 줄인다.0이면 진행 중인 요청이 없으므로 종료됩니다.

$('#button').click(function() {
    var inProgress = 0;

    function handleBefore() {
        inProgress++;
    };

    function handleComplete() {
        if (!--inProgress) {
            // do what's in here when all requests have completed.
        }
    };

    $.ajax({
        beforeSend: handleBefore,
        complete: function () {
            // whatever
            handleComplete();
            // whatever
        }
    });
    $.ajax({
        beforeSend: handleBefore,
        complete: function () {
            // whatever
            handleComplete();
            // whatever
        }
    });
    $.ajax({
        beforeSend: handleBefore,
        complete: function () {
            // whatever
            handleComplete();
            // whatever
        }
    });
});

$.when는 모든 로 상정하고 으로 Ajax는 Ajax입니다.$.when 함께 .apply()다음과 같이 합니다.

// Save all requests in an array of jqXHR objects
var requests = arrayOfThings.map(function(thing) {
    return $.ajax({
        method: 'GET',
        url: 'thing/' + thing.id
    });
});

$.when.apply(this, requests).then(function(resp1, resp2/*, ... */) {
    // Each argument is an array with the following structure: [ data, statusText, jqXHR ]
    var responseArgsArray = Array.prototype.slice.call(this, arguments);

});

스프레드 구문을 사용하면 다음과 같이 코드를 쓸 수 있습니다.

$.when(...requests).then((...responses) => {
    // do something with responses
})

그 이유는$.when를 받아들입니다.

$.when(ajaxRequest1, ajaxRequest2, ajaxRequest3);

그리고 이렇게는 안 돼

$.when([ajaxRequest1, ajaxRequest2, ajaxRequest3]);

나는 hvgotcodes의 아이디어가 좋다.여기서 제안하는 것은 완전한 번호와 필요한 번호를 비교하여 최종 콜백을 실행하는 범용 인크리더를 추가하는 것입니다.이것은 최종 콜백에 짜넣을 수 있습니다.

var sync = {
 callbacksToComplete = 3,
 callbacksCompleted = 0,
 addCallbackInstance = function(){
  this.callbacksCompleted++;
  if(callbacksCompleted == callbacksToComplete) {
   doFinalCallBack();
  }
 }
};

[이름 업데이트를 반영하여 편집]

EDIT - 아마도 가장 좋은 옵션은 세 가지 요청이 수행하는 모든 작업을 수행하는 서비스 엔드포인트를 작성하는 것입니다.이렇게 하면 하나의 요청만 수행하면 모든 데이터가 응답에서 필요한 위치에 배치됩니다.같은 요구를 3회 반복하고 있는 경우는, 이 루트를 사용하는 것이 좋습니다.일반적으로 사용되는 소규모 서버 액션을 하나로 묶는 파사드 서비스를 서버에 설정하는 것이 좋은 설계 결정인 경우가 많습니다.생각일 뿐이야.


이를 위한 한 가지 방법은 Ajax 호출 전에 클릭 핸들러에 '동기' 개체를 만드는 것입니다.뭐랄까

var sync = {
   count: 0
}

동기화는, 성공 콜의 범위에 자동적으로 바인드 됩니다(폐쇄).성공 핸들러에서는 카운트를 증가시켜 3의 경우 다른 함수를 호출할 수 있습니다.

또는 다음과 같은 작업을 수행할 수 있습니다.

var sync = {
   success1Complete: false,
   ...
   success3Complete: false,
}

각 성공이 실행되면 동기 값이 true로 변경됩니다.계속 진행하기 전에 동기화를 확인하여 세 가지 모두 참인지 확인해야 합니다.

xhrs 중 하나가 성공을 반환하지 않는 경우, 그 점을 고려해야 합니다.

또한 성공 핸들러의 최종 함수를 호출하여 동기 옵션에 액세스하여 실제로 작업을 수행할지 여부를 결정하는 방법도 있습니다.다만, 동기화가 그 기능의 범위내에 있는 것을 확인할 필요가 있습니다.

대기열을 배열하는 추가 방법 없이 더 쉽게 수행할 수 있는 방법을 찾았습니다.

JS

$.ajax({
  type: 'POST',
  url: 'ajax1.php',
  data:{
    id: 1,
    cb:'method1'//declaration of callback method of ajax1.php
  },
  success: function(data){
  //catching up values
  var data = JSON.parse(data);
  var cb=data[0].cb;//here whe catching up the callback 'method1'
  eval(cb+"(JSON.stringify(data));");//here we calling method1 and pass all data
  }
});


$.ajax({
  type: 'POST',
  url: 'ajax2.php',
  data:{
    id: 2,
    cb:'method2'//declaration of callback method of ajax2.php
  },
  success: function(data){
  //catching up values
  var data = JSON.parse(data);
  var cb=data[0].cb;//here whe catching up the callback 'method2'
  eval(cb+"(JSON.stringify(data));");//here we calling method2 and pass all data
  }
});


//the callback methods
function method1(data){
//here we have our data from ajax1.php
alert("method1 called with data="+data);
//doing stuff we would only do in method1
//..
}

function method2(data){
//here we have our data from ajax2.php
alert("method2 called with data="+data);
//doing stuff we would only do in method2
//..
}

PHP(ajax1.php)

<?php
    //catch up callbackmethod
    $cb=$_POST['cb'];//is 'method1'

    $json[] = array(
    "cb" => $cb,
    "value" => "ajax1"
    );      

    //encoding array in JSON format
    echo json_encode($json);
?>

PHP(ajax2)php)

<?php
    //catch up callbackmethod
    $cb=$_POST['cb'];//is 'method2'

    $json[] = array(
    "cb" => $cb,
    "value" => "ajax2"
    );      

    //encoding array in JSON format
    echo json_encode($json);
?>

조금 전에 같은 질문을 했는데, 여기서 몇 가지 좋은 답변을 얻었습니다: 일련의 비동기식 XHR 호출 후 '콜백'을 추가하는 가장 좋은 방법입니다.

나는 이 페이지의 답변에서 좋은 힌트를 얻었다.내 용도에 맞게 조금 수정해서 공유할 수 있을 것 같았어.

// lets say we have 2 ajax functions that needs to be "synchronized". 
// In other words, we want to know when both are completed.
function foo1(callback) {
    $.ajax({
        url: '/echo/html/',
        success: function(data) {
            alert('foo1');
            callback();               
        }
    });
}

function foo2(callback) {
    $.ajax({
        url: '/echo/html/',
        success: function(data) {
            alert('foo2');
            callback();
        }
    });
}

// here is my simplified solution
ajaxSynchronizer = function() {
    var funcs = [];
    var funcsCompleted = 0;
    var callback;

    this.add = function(f) {
        funcs.push(f);
    }

    this.synchronizer = function() {
        funcsCompleted++;
        if (funcsCompleted == funcs.length) {
            callback.call(this);
        }
    }

    this.callWhenFinished = function(cb) {
        callback = cb;
        for (var i = 0; i < funcs.length; i++) {
            funcs[i].call(this, this.synchronizer);
        }
    }
}

// this is the function that is called when both ajax calls are completed.
afterFunction = function() {
    alert('All done!');
}

// this is how you set it up
var synchronizer = new ajaxSynchronizer();
synchronizer.add(foo1);
synchronizer.add(foo2);
synchronizer.callWhenFinished(afterFunction);

여기에는 몇 가지 제한이 있지만, 제 경우는 괜찮았습니다.또, 보다 고도의 것에 대해서는, 도움이 되는 AOP 플러그 인(jQuery용)도 있습니다.http://code.google.com/p/jquery-aop/

나는 오늘 이 문제를 발견했고, 이것은 받아들여진 답을 보기 전에 나의 순진한 시도였다.

<script>
    function main() {
        var a, b, c
        var one = function() {
            if ( a != undefined  && b != undefined && c != undefined ) {
                alert("Ok")
            } else {
                alert( "¬¬ ")
            }
        }

        fakeAjaxCall( function() {
            a = "two"
            one()
        } )
        fakeAjaxCall( function() {
            b = "three"
            one()
        } )
        fakeAjaxCall( function() {
            c = "four"
            one()
        } )
    }
    function fakeAjaxCall( a ) {
        a()
    }
    main()
</script>

jquery가 아니라 jquery가 실행 가능한 솔루션을 가지고 있는 것 같습니다만, 또 하나의 옵션으로서…

SharePoint 웹 서비스를 사용할 때도 비슷한 문제가 있었습니다. 단일 프로세스에 대한 입력을 생성하기 위해 여러 소스에서 데이터를 가져와야 하는 경우가 많습니다.

이를 해결하기 위해 AJAX 추상화 라이브러리에 이러한 기능을 포함시켰습니다.완료되면 핸들러 세트를 트리거하는 요청을 쉽게 정의할 수 있습니다.단, 각 요구는 여러 http 콜을 사용하여 정의할 수 있습니다.컴포넌트(및 상세 매뉴얼)는 다음과 같습니다.

DPAJAX (DepressedPress.com )

이 간단한 예에서는 3개의 콜을 사용하여1개의 요구를 작성하고 그 정보를 콜 순서로1개의 핸들러에 전달합니다.

    // The handler function 
function AddUp(Nums) { alert(Nums[1] + Nums[2] + Nums[3]) }; 

    // Create the pool 
myPool = DP_AJAX.createPool(); 

    // Create the request 
myRequest = DP_AJAX.createRequest(AddUp); 

    // Add the calls to the request 
myRequest.addCall("GET", "http://www.mysite.com/Add.htm", [5,10]); 
myRequest.addCall("GET", "http://www.mysite.com/Add.htm", [4,6]); 
myRequest.addCall("GET", "http://www.mysite.com/Add.htm", [7,13]); 

    // Add the request to the pool 
myPool.addRequest(myRequest); 

다른 많은 솔루션(jquery의 "when" 솔루션 포함)과는 달리 이 메서드는 콜의 단일 스레드화를 강제하지 않습니다.각각의 스레드화는 환경이 허용하는 한 빠르게(또는 느리게) 실행되지만 단일 핸들러는 모두 완료된 후에만 호출됩니다.또, 타임 아웃치를 설정해, 서비스가 약간 실패했을 경우는 재시도 할 수도 있습니다.

나는 그것이 매우 유용하다는 것을 알았다(그리고 코드 관점에서 이해하는 것은 매우 간단했다).체인이 없어지고 콜이 카운트되지 않으며 출력이 저장됩니다.'설정하고 잊어버려'

네, 오래된 방법이지만 제 솔루션을 제안해 주십시오.

function sync( callback ){
    syncCount--;
    if ( syncCount < 1 ) callback();
}
function allFinished(){ .............. }

window.syncCount = 2;

$.ajax({
    url: 'url',
    success: function(data) {
        sync( allFinished );
    }
});
someFunctionWithCallback( function(){ sync( allFinished ); } )

콜백 기능이 있는 함수에서도 동작합니다.syncCount를 설정하고 모든 액션의 콜백에서 함수 sync(...)를 호출합니다.

async   : false,

기본적으로는 모든 요청이 비동기적으로 전송됩니다(즉, 기본적으로는 true로 설정됩니다).동기 요청이 필요한 경우 이 옵션을 로 설정하십시오. 교차 도메인 요청 및dataType: "jsonp"요청은 동기 조작을 지원하지 않습니다.동기요구는 일시적으로 브라우저를 잠그고 요청이 활성화되어 있는 동안 모든 액션이 비활성화될 수 있습니다.jQuery 1.8에서는async: falsejqXHR 사용($.Deferred는 권장되지 않습니다.jqXHR 객체의 대응하는 메서드 대신 success/error/complete 콜백옵션을 사용해야 합니다.jqXHR.done()또는 폐지된jqXHR.success().

$.ajax({type:'POST', url:'www.naver.com', dataType:'text', async:false,
    complete:function(xhr, textStatus){},
    error:function(xhr, textStatus){},
    success:function( data ){
        $.ajax({type:'POST', 
            ....
            ....
            success:function(data){
                $.ajax({type:'POST',
                    ....
                    ....
            }
        }
    });

죄송하지만 제가 영어를 한 마디도 못하는 한국 사람이기 때문에 제가 무엇을 원하는지 설명할 수 없지만, 당신은 쉽게 이해할 수 있을 거예요.

언급URL : https://stackoverflow.com/questions/4368946/jquery-callback-for-multiple-ajax-calls

반응형