2013-02-26 3 views
1

일부 지연 콜드 객체를 사용하여 콜백을 관리하려고합니다. 쉬운 경우를 알아 냈습니다 :지연 개체를 콜백이 거부해야하는 경우 수동으로 해결할 수 있습니까?

var deferred = $.Deferred(); 

deferred.done(function() { 
    console.log('done'); 
}); 

var json = $.getJSON('/foo'); 

json.then(
    function() { 
     deferred.resolveWith(this, arguments); 
    } 
); 

그러나 해결/거부하기 전에 응답을 검사해야합니다. 나는 이런 식으로 뭔가를 추가하고 싶습니다 :

deferred.pipe(
    function(response) { 
     if (response.message === 'error') { 
      return $.Deferred.reject(response); 
     } 
     return response; 
    } 
); 

을하지만 내가 할 때, 내 원래 done() 콜백 관계없이 항상라고합니다. 나는 일단 전화를 걸면 deferred.resolveWith()을 "롤백"하고 나중에 거부 된 것으로 표시하기에는 너무 늦기 때문에 확신합니다. 나는 조건부를 json.then()에 대한 첫 번째 인수로 옮길 수 있다는 것을 알고 있지만 지연된 객체의 요점을 놓치고있는 것처럼 보입니다.이 모든 동작을 단일 장소에 캡슐화하기위한 것이라는 생각이 들었습니다.

조건부 호출과 콜백을 모두 deferred에 넣을 수 있습니까? 다른 곳에서도 해결할 수 있습니까?

+1

최근 버전에서는'.pipe'가 감가 상각되었습니다.'.then'을 사용합니다. –

+0

원래 코드에 deferred.pipe가 어디에 적합합니까? 요청의 매개 변수를 요청 완료 콜백에서 분리해야하는 이유를 이해하지 못합니다. 이미 완료 콜백에서 해결되었으므로 되돌아 가서 거부 할 수는 없습니다. –

+0

@KevinB deferred.pipe (또는 deferred.then)는 지연된 나머지가 정의 된 곳으로 갈 수 있고, ajax 호출 이후에 갈 수는 없다. 그리고 내 질문은 개념적 인 것일 수도 있습니다 - 어쩌면 단일 객체에서 응답 테스트와 콜백 모두를 캡슐화하는 것이 적절하지 않을 수 있습니다. 그러나이 경우 아약스 호출 자체는 일련의 조건문과 콜백에 중첩됩니다. 워크 플로우를 단일 객체로 정의하고 나중에 그것을 참조하는 것이 모듈화하는 가장 좋은 방법 인 것처럼 보였습니다. –

답변

3

실제로 목표를 두 단계로 구분하는 것만 같습니다 : ajax 요청의 결과를 확인한 다음 결과를 처리하십시오. 그렇게하기 위해 외부 지연을 ajax 요청에 의해 반환 된 매개 변수를 기반으로 해결하거나 거부하는 내부 지연으로 대체하십시오.

var deferred = $.Deferred(); 

deferred.then(function(data){ 
    // new deferred that we will be returning 
    var deferred = $.Deferred(); 
    if (data.success == true) { 
     deferred.resolveWith(data.result); 
    } 
    else { 
     deferred.rejectWith(data.error); 
    } 
    // any following chained methods will affect this returned deferred object 
    return deferred; 
}).then(
    // done callback 
    function(result){ 
     console.log("Resolved!"); 
     console.dir(result); 
    }, 
    // fail callback 
    function(error){ 
     console.log("Rejected!"); 
     console.dir(error) 
    } 
); 

var json = $.getJSON("/foo"); 
json.done(deferred.resolveWith);