2014-09-10 2 views
0

우리는 AJAX 웹 응용 프로그램을 가지고 있으며 우리가 공통적으로 갖고있는 패턴은 하나씩 차례로 호출하는 수많은 ajax 호출입니다. 이는 첨부 된 여러 엔터티가있는 항목을 저장할 때 일반적입니다. 예 : saveCustomer() ->saveCustomerAddress() ->saveCustomersOrder() 일 수 있습니다. methodA()가이 성공하면 첫 번째 방법, 즉,이 등 (아래 코드 참조) methodB()를 호출하고 있도록체인 AJAX 호출을위한 패턴을 찾고

우리는 현재 그것이있다. 이 패턴의 단점은 무엇이 진행되고 있는지보기가 정말로 어렵다는 것입니다. methodA()을 읽는 경우 메서드 이름을 읽지 않아도 메서드 B()메서드 C()이 호출됩니다. 다른 단점은 체인을 변경하려는 경우 많은 코드를 다시 작성해야하며 메서드를 개별적으로 호출하려는 경우 메서드 다운 스트림을 호출하기 때문에 수행 할 수 없다는 것입니다.

function Tester() { 
    this.url = 'https://public.opencpu.org/ocpu/library/'; 

    this.save = function() { 
     this.methodA(); 
    } 

    this.methodA = function() { 
     var self = this; 

     $.ajax({ 
      url: self.url, 
      async: true 
     }).always(function (processedDataOrXHRWrapper, textStatus, xhrWrapperOrErrorThrown) { 

      //check for errors... and if OK 
      alert('A OK'); 
      self.methodB(); 

     }) 
    } 
    this.methodB = function() { 
     var self = this; 

     $.ajax({ 
      url: self.url, 
      async: true 
     }).always(function (processedDataOrXHRWrapper, textStatus, xhrWrapperOrErrorThrown) { 

      //check for errors... and if OK 
      alert('B OK'); 
      self.methodC(); 

     }) 
    } 
    this.methodC = function() { 
     var self = this; 

     $.ajax({ 
      url: self.url, 
      async: true 
     }).always(function (processedDataOrXHRWrapper, textStatus, xhrWrapperOrErrorThrown) { 
      //OK 
      alert('C OK'); 
     }) 
    } 
} 
new Tester().save(); 

나는 더 나은 패턴을 찾기 위해 머리를 긁적입니다. 콜백 함수에서 나중의 메서드를 마무리 할 수있는 방법을 생각한 다음 각 메서드를 통해 전달하지만 실제로이 방법에 접근 할 방법이 확실하지 않습니다.

체인 방법을 사용할 때 메소드 의존성을 제거 할 수있는 일반적인 유형의 패턴을 알고있는 사람이 있습니까?

+3

사용 약정. jQuery에는이 라이브러리 나 다른 라이브러리가있다. 여기를보십시오 : http://stackoverflow.com/questions/11539605/chain-of-jquery-promises 또는 여기 http://www.dotnetcurry.com/showarticle.aspx?ID=1022 –

+0

아니면, 덜 고급, 그냥 콜백을 사용합니다 ... – Bergi

답변

3
function A() { 
    writeMessage("Calling Function A"); 
    return $.ajax({ 
     url: "/scripts/S9/1.json", 
     type: "GET",      
     dataType: "json" 
    }); 
} 


function B(resultFromA) { 
    writeMessage("In Function B. Result From A = " + resultFromA.data); 
    return $.ajax({ 
     url: "/scripts/S9/2.json", 
     type: "GET", 
     dataType: "json" 
    }); 
} 


function C(resultFromB) { 
    writeMessage("In Function C. Result From B = " + resultFromB.data); 
    return $.ajax({ 
     url: "/scripts/S9/3.json", 
     type: "GET", 
     dataType: "json" 
    }); 
} 

function D(resultFromC) { 
    writeMessage("In Function D. Result From C = " + resultFromC.data); 
} 

A().then(B).then(C).then(D); 

function writeMessage(msg) { 
    $("#para").append(msg + "</br>");     
} 
+0

다른 답변과 다른 점은 무엇입니까? 아약스 전화로 돌아 오는 중입니까? 그러면 비동기가되는 것을 막을 수 있습니까? –

+1

jQuery Doc : 콜백은 추가 된 순서대로 실행됩니다. deferred.then가 Promise를 반환하기 때문에, Promise 객체의 다른 메소드는 추가 .then() 메소드를 포함하여이 객체에 연결될 수 있습니다. 그리고 그것이 우리가 여기서하고있는 일입니다. 모든 Ajax jQuery 메서드는 이미 약속을 반환합니다. 함수 A에서 Ajax 호출이 완료되면 약속을 해결합니다. 함수 B()는 Ajax 호출의 결과를 첫 번째 인수로 호출합니다. B()에서 ajax 호출이 완료되면 약속 및 함수 C()가 해당 호출의 결과와 함께 호출되는 등을 해결합니다. – Rotka

+0

알았습니다. 나는 그의 해결책을 여기에 맞추기 위해 코드를 변경했다. http://jsfiddle.net/h8tfrvy4/2/ –

0

이 시도 :

function Tester() { 
    var self = this; 
    this.url = 'https://public.opencpu.org/ocpu/library/'; 

    this.save = function() { 
     self.methodA().then(self.methodB()).then(self.methodC()) 
    } 

    this.methodA = function() { 
     var self = this; 

     return $.ajax({ 
      url: self.url, 
      async: true 
     }).always(function (processedDataOrXHRWrapper, textStatus, xhrWrapperOrErrorThrown) { 

      //check for errors... and if OK 
      alert('A OK'); 


     }) 
    } 
    this.methodB = function() { 
     var self = this; 

     return $.ajax({ 
      url: self.url, 
      async: true 
     }).always(function (processedDataOrXHRWrapper, textStatus, xhrWrapperOrErrorThrown) { 

      //check for errors... and if OK 
      alert('B OK'); 


     }) 
    } 
    this.methodC = function() { 
     var self = this; 

     return $.ajax({ 
      url: self.url, 
      async: true 
     }).always(function (processedDataOrXHRWrapper, textStatus, xhrWrapperOrErrorThrown) { 
      //OK 

     }) 
    } 
} 
new Tester().save(); 
+0

정교하게 : jQuery의 Ajax 구현에 내장 된 Promises를 사용하고 있습니다. 더 많은 정보는 jQuery 문서에서 찾을 수 있습니다. – ajm

+0

하지만 잘못 사용하고 있습니다. '.then()'에 콜백을 전달해야합니다! – Bergi

+0

나는 왜 누군가가 당신에게 부정적인 표를 주 었는지를 모른다. 이것은 잘 작동하는 것 같습니다. –

1

는이 같은 동적 호출을 사용할 수 있습니다

 this.reqChain = ['req_1', 'req_2']; 

     this.callChain = function(){ 
      if(!self.reqChain.length) return; 
      ajax({ 
       url: self.reqChain[0], 
       async: true,   
       always: function(processedDataOrXHRWrapper, textStatus, whrWrapperOrErrorThrown){ 
        self.reqChain.shift(); 
        $(document).trigger('request_'+self.reqChain[0]+'_callback', [processedDataOrXHRWrapper, textStatus, whrWrapperOrErrorThrown]) 
        self.callChain(); 
       } 
      }); 
    } 

당신은 콜백을 전달할 수 있습니다 또는 동적 이벤트에 바인딩 할 수 있습니다.

1

내 대답은 다음과 같습니다. 함수에서 모든 메서드를 래핑하고 콜백을 통해 메서드에 전달합니다.

일을하는 것처럼 보입니다. 누구든지 의견이 있습니까?

function Tester2() { 

    this.save = function() { 

     var self = this; 

     var callbackC = function() { 
      self.methodC(); 
     } 

     var callbackB = function() { 
      self.methodB(callbackC); 
     } 

     this.methodA(callbackB); 

    } 

    this.methodA = function (callbackFn) { 
     var self = this; 

     $.ajax({ 
      url: self.url, 
      async: true 
     }).always(function (processedDataOrXHRWrapper, textStatus, xhrWrapperOrErrorThrown) { 


      //check for errors... and if OK 
      alert('A OK'); 
      if (callbackFn) 
       callbackFn(); 

     }) 
    } 
    this.methodB = function (callbackFn) { 
     var self = this; 

     $.ajax({ 
      url: self.url, 
      async: true 
     }).always(function (processedDataOrXHRWrapper, textStatus, xhrWrapperOrErrorThrown) { 


      //check for errors... and if OK 
      alert('B OK'); 
      if (callbackFn) 
       callbackFn(); 

     }) 
    } 
    this.methodC = function() { 
     var self = this; 

     $.ajax({ 
      url: self.url, 
      async: true 
     }).always(function (processedDataOrXHRWrapper, textStatus, xhrWrapperOrErrorThrown) { 
      //OK 
      alert('C OK'); 
     }) 
    } 
} 

new Tester2().save(); 
+0

예, 그건 완전히 괜찮습니다. (내 의견 "* 또는 덜 진보 된 것, 그냥 콜백을 사용하는 것 ... *") - 그 외에도'.always'는 에러를 무시합니다. 약속보다 콜백에 익숙하다면 이해하기 쉽습니다. 허용되는 @Rotka의 대답은 좀 더 간결하며 약속은보다 우아하게 간주됩니다. – Bergi

관련 문제